实例代码讲解JAVA多线程

下面我将详细讲解“实例代码讲解JAVA多线程”的完整攻略,包含如下内容:

一、多线程基础知识

1. 线程的概念及创建

线程是指在单个程序中同时运行的多个执行单元,每个线程都有独立的执行路径。Java中通过继承Thread类或实现Runnable接口的方式创建线程,具体代码实例如下:

public class MyThread extends Thread {
    public void run() {
        System.out.println("MyThread running...");
    }
}

public class Main {
    public static void main(String[] args) {
        MyThread thread = new MyThread();
        thread.start();
        System.out.println("Main thread running...");
    }
}

运行以上代码,控制台将输出:

Main thread running...
MyThread running...

这证明主线程和子线程是交替运行的。

2. 线程的状态

Java中线程有五种状态:新建(NEW)、就绪(RUNNABLE)、运行(RUNNING)、阻塞(BLOCKED)和死亡(DEAD)。线程的状态由操作系统内核维护和切换。

3. 线程的同步与互斥

多个线程执行时访问共享资源会发生冲突,需要进行同步或互斥处理,防止出现数据不一致等问题。Java中通过synchronized关键字进行同步,通过Lock接口进行互斥。

二、Java多线程实例

1. 生产者消费者模型

生产者消费者模型是多个线程协作的典型场景,生产者生产数据并交给缓冲区,消费者从缓冲区取出数据进行消费。以下代码实现生产者消费者模型:

public class Producer extends Thread {
    private Buffer buffer;
    public Producer(Buffer buffer) {
        this.buffer = buffer;
    }
    public void run() {
        for (int i=1; i<=10; i++) {
            buffer.put(i);
            System.out.println("Producer produce: " + i);
            try {
                Thread.sleep((int)(Math.random() * 200));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("Producer finished producing.");
    }
}

public class Consumer extends Thread {
    private Buffer buffer;
    public Consumer(Buffer buffer) {
        this.buffer = buffer;
    }
    public void run() {
        for (int i=1; i<=10; i++) {
            int num = buffer.get();
            System.out.println("Consumer consume: " + num);
            try {
                Thread.sleep((int)(Math.random() * 200));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("Consumer finished consuming.");
    }
}

public class Buffer {
    private int[] buffer = new int[10];
    private int head = 0;
    private int tail = 0;
    private int count = 0;

    public synchronized void put(int num) {
        while (count == buffer.length) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        buffer[tail] = num;
        tail = (tail + 1) % buffer.length;
        count++;
        notifyAll();
    }

    public synchronized int get() {
        while (count == 0) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        int num = buffer[head];
        head = (head + 1) % buffer.length;
        count--;
        notifyAll();
        return num;
    }
}

public class Main {
    public static void main(String[] args) {
        Buffer buffer = new Buffer();
        Producer producer = new Producer(buffer);
        Consumer consumer = new Consumer(buffer);
        producer.start();
        consumer.start();
    }
}

这段代码实现了一个简单的生产者消费者模型,通过使用synchronized关键字,实现了对缓冲区的同步访问和互斥访问,生产者可以把数据放入缓冲区,消费者可以从缓冲区取出数据进行消费,两个线程之间互相协作完成工作。

2. 线程池

多线程编程时,频繁地创建和销毁线程会带来大量的资源消耗,此时应该采用线程池的机制,将线程的创建和生命周期管理由线程池来负责。以下代码实现一个简单的线程池:

public class ThreadPool {
    private List<WorkerThread> threads = new ArrayList<WorkerThread>();
    private LinkedBlockingQueue<Runnable> taskQueue = new LinkedBlockingQueue<Runnable>();
    private boolean stopped = false;

    public ThreadPool(int numThreads) {
        for (int i=0; i<numThreads; i++) {
            WorkerThread thread = new WorkerThread();
            threads.add(thread);
            thread.start();
        }
    }
    public void execute(Runnable task) {
        synchronized (taskQueue) {
            taskQueue.add(task);
            taskQueue.notifyAll();
        }
    }
    public void shutdown() {
        stopped = true;
        synchronized (taskQueue) {
            taskQueue.notifyAll();
        }
        for (WorkerThread thread : threads) {
            try {
                thread.join();
            } catch (InterruptedException e) {}
        }
    }
    private class WorkerThread extends Thread {
        public void run() {
            while (!stopped) {
                Runnable task = null;
                synchronized (taskQueue) {
                    if (taskQueue.isEmpty()) {
                        try {
                            taskQueue.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    task = taskQueue.poll();
                }
                if (task != null) {
                    task.run();
                }
            }
        }
    }
}

public class Main {
    public static void main(String[] args) {
        ThreadPool pool = new ThreadPool(2);
        for (int i=1; i<=10; i++) {
            final int num = i;
            pool.execute(new Runnable() {
                public void run() {
                    System.out.println("Executing task " + num + " on thread " + Thread.currentThread().getName());
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
        pool.shutdown();
    }
}

这段代码实现了一个具备固定线程数的线程池,可以提交多个任务到线程池并按顺序执行,线程池内的线程在任务处理完毕后会一直存在,等待下一个任务的到来。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:实例代码讲解JAVA多线程 - Python技术站

(0)
上一篇 2023年5月17日
下一篇 2023年5月17日

相关文章

  • java多线程开启的三种方式你知道吗

    当我们需要在Java程序中同时执行多个任务时,可以使用多线程技术来提高程序的效率和响应能力。Java中开启多线程的方式有三种: 继承Thread类并重写run()方法 实现Runnable接口并实现run()方法 实现Callable接口并实现call()方法 1. 继承Thread类并重写run()方法 继承Thread类的方式是最简单也是最常用的开启新线…

    多线程 2023年5月17日
    00
  • Apache限制IP并发数和流量控制的方法

    当网站访问量较大时,为了防止某些IP用户访问过于频繁占用服务器资源,或者避免流量峰值对服务器的影响,我们可以通过限制IP并发数和流量控制来保障服务器的稳定性。下面是关于如何使用Apache来实现这两个目标的攻略。 限制IP并发数 步骤1:安装mod_evasive模块 首先,需要安装Apache的mod_evasive模块。在Linux系统中,可以直接通过以…

    多线程 2023年5月16日
    00
  • 详解java解决分布式环境中高并发环境下数据插入重复问题

    详解 Java 解决分布式环境中高并发环境下数据插入重复问题 背景 在高并发环境下,数据插入操作很容易出现重复插入的问题。例如,多个用户同时提交一个相同的表单,系统可能会将同样的数据插入数据库中多次,造成数据不一致的问题。这种情况在分布式环境下尤其常见,因为不同节点的时间戳可能不一致。 解决方案 方法一:利用 Unique 约束 在数据库中设置 Unique…

    多线程 2023年5月16日
    00
  • 浅谈多线程_让程序更高效的运行

    浅谈多线程:让程序更高效的运行 什么是多线程? 多线程是指一个程序运行时,同时运行多个线程(线程是指一个程序内部的一个执行流程)。简单来说,多线程可以让程序同时完成多个任务,从而提高程序的执行效率。 为什么使用多线程? 在某些情况下,单线程的程序可能会变得非常慢,甚至耗费大量的时间来执行任务。这时,使用多线程可以让程序同时完成多个任务,提高程序的执行效率。 …

    多线程 2023年5月17日
    00
  • java并发包JUC同步器框架AQS框架原文翻译

    Java并发包JUC同步器框架AQS框架原文翻译 简介 JUC是Java Util Concurrent(Java工具包并发),是一个用于管理多线程的库。其中,同步器框架AQS(AbstractQueuedSynchronizer)是JUC的核心,它提供了一种底层机制,可以用于实现各种同步器,如ReentrantLock、CountDownLatch和Sem…

    多线程 2023年5月16日
    00
  • java多线程实现文件下载

    实现文件下载的过程中,可以通过使用多线程技术来提高文件下载速度。在Java中,可以利用Java多线程机制实现文件下载。下面是一个具体的实现攻略。 1. 多线程下载原理 多线程下载的原理是将一个大文件划分为若干个较小的文件块,每个线程分别下载不同的文件块。通过多个线程同时下载不同的文件块,可以加快整个文件的下载速度。同时,在下载过程中还需要考虑线程的安全性问题…

    多线程 2023年5月16日
    00
  • Java多线程高并发中解决ArrayList与HashSet和HashMap不安全的方案

    为了解决Java多线程高并发中ArrayList、HashSet和HashMap不安全的问题,有以下几种方案可以选择。 使用线程安全的数据结构 可以使用线程安全的数据结构,如CopyOnWriteArrayList,ConcurrentHashMap。这些数据结构在多线程环境下可以保证线程安全,但是读写性能相对较低。 其中,CopyOnWriteArrayL…

    多线程 2023年5月17日
    00
  • Java多线程回调方法实例解析

    Java多线程回调方法实例解析 什么是回调方法 在Java中,回调方法是指将一个方法作为参数传递给另一个方法,并在另一个方法执行后,调用传入的方法。这种方式可以让我们将一个方法的执行结果传递给另一个方法,从而实现代码的复用和解耦。 为什么要使用多线程回调方法 在多线程编程中,需要处理并发执行的任务。一个任务执行完成后,需要通知其他任务执行相关的代码,这时就需…

    多线程 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部