解密Java多线程:让线程之间默契无间的通讯和协作技巧

解密Java多线程:让线程之间默契无间的通讯和协作技巧多线程是计算机科学中非常重要的一个概念,它可以提高程序的执行效率,充分利用计算机的资源。在 Java 编程中,多线程也很常见,Java 提供了丰

欢迎大家来到IT世界,在知识的湖畔探索吧!

多线程是计算机科学中非常重要的一个概念,它可以提高程序的执行效率,充分利用计算机的资源。在 Java 编程中,多线程也很常见,Java 提供了丰富的多线程库支持。但是多线程也存在一些困难,如线程间的通讯、协作等问题。本文将深入探讨如何让线程之间默契无间地通讯和协作,帮助读者更好地理解和应用 Java 多线程。

摘要

本文将介绍 Java 多线程中的线程通讯和协作技巧。首先讨论了线程通讯的基本原理,包括 wait(), notify() 和 notifyAll() 等方法的使用。然后,介绍了线程协作的概念和常见技巧,如使用 Semaphore、CountDownLatch 和 CyclicBarrier 等工具类。最后,通过代码实现多个线程之间的通讯和协作,并提供了测试用例。

线程通讯

线程通讯是指多个线程之间的信息交换和协作。在 Java 中,线程通讯主要通过共享对象的方式实现。多个线程共享一个对象,通过该对象的方法实现线程之间的通讯。

wait() 和 notify()

wait() 和 notify() 是 Java 中实现线程通讯的两个重要方法。它们都属于 Object 类,任何一个 Java 对象都可以调用这两个方法。其基本思想是在一个共享对象上进行操作,使线程挂起或唤醒。

wait() 方法的作用是使当前线程进入等待状态,直到其他线程调用了该对象的 notify() 或 notifyAll() 方法唤醒它。

public synchronized void wait() throws InterruptedException;
public synchronized void wait(long timeout) throws InterruptedException;
public synchronized void wait(long timeout, int nanos) throws InterruptedException;

欢迎大家来到IT世界,在知识的湖畔探索吧!

notify() 方法的作用是唤醒一个等待该对象的线程。

欢迎大家来到IT世界,在知识的湖畔探索吧!public synchronized void notify();

notifyAll() 方法的作用是唤醒所有等待该对象的线程。

public synchronized void notifyAll();

代码示例

下面是一个经典的生产者-消费者模型,使用 wait() 和 notify() 方法实现线程通讯。

生产者线程:

欢迎大家来到IT世界,在知识的湖畔探索吧!class Producer implements Runnable {
    private Queue<String> queue;
    private int maxSize;
    private int i = 0;

    public Producer(Queue<String> queue, int maxSize) {
        this.queue = queue;
        this.maxSize = maxSize;
    }

    @Override
    public void run() {
        while (true) {
            synchronized (queue) {
                while (queue.size() == maxSize) { // 当队列满了,生产者线程等待
                    try {
                        queue.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                queue.offer("message" + (++i));
                System.out.println("produce: " + i);
                queue.notifyAll(); // 生产者线程生产完消息,唤醒所有等待队列的线程
            }
        }
    }
}

消费者线程:

class Consumer implements Runnable {
    private Queue<String> queue;

    public Consumer(Queue<String> queue) {
        this.queue = queue;
    }

    @Override
    public void run() {
        while (true) {
            synchronized (queue) {
                while (queue.isEmpty()) { // 当队列为空,消费者线程等待
                    try {
                        queue.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                String message = queue.poll();
                System.out.println("consume: " + message);
                queue.notifyAll(); // 消费者线程消费完消息,唤醒所有等待队列的线程
            }
        }
    }
}

测试代码:

public static void main(String[] args) {
    Queue<String> queue = new LinkedList<>();
    int maxSize = 5;
    Thread producerThread = new Thread(new Producer(queue, maxSize));
    Thread consumerThread = new Thread(new Consumer(queue));
    producerThread.start();
    consumerThread.start();
}

测试结果如下:

解密Java多线程:让线程之间默契无间的通讯和协作技巧

线程协作

线程协作是指多个线程之间相互协作,共同完成一个任务。在 Java 中,线程协作主要通过工具类实现。常见的工具类有 Semaphore、CountDownLatch 和 CyclicBarrier 等。

Semaphore

Semaphore 是 Java 中一个基于计数器的同步工具类,用来控制同时访问某个资源的线程数量。它通过 acquire() 和 release() 方法来协调线程的运行。

public Semaphore(int permits);
public Semaphore(int permits, boolean fair);

public void acquire() throws InterruptedException;
public void acquire(int permits) throws InterruptedException;
public void release();
public void release(int permits);

其中 permits 表示资源的数量,fair 表示使用公平或非公平的机制。当 permits 大于 1 时,表示多线程可以同时访问资源。

CountDownLatch

CountDownLatch 是 Java 中一个基于计数器的同步工具类,用来协调多个线程之间的运行。它通过 await() 和 countDown() 方法来协调线程的运行。

public CountDownLatch(int count);

public void await() throws InterruptedException;
public boolean await(long timeout, TimeUnit unit) throws InterruptedException;
public void countDown();
public long getCount();

其中 count 表示需要完成的任务数量。当 count 减为 0 时,所有的线程将被唤醒。

CyclicBarrier

CyclicBarrier 是 Java 中一个同步工具类,用来协调多个线程之间的运行。它允许多个线程在某个屏障处阻塞,直到所有线程都到达该屏障后才能继续执行。

public CyclicBarrier(int parties);

public CyclicBarrier(int parties, Runnable barrierAction);

public void await() throws InterruptedException, BrokenBarrierException;
public int await(long timeout, TimeUnit unit) throws InterruptedException, BrokenBarrierException, TimeoutException;

其中 parties 表示需要等待的线程数量。当所有的线程都到达该屏障后,可以选择执行 barrierAction。当最后一个线程到达该屏障后,所有的线程将被唤醒。

代码示例

下面是一个使用 Semaphore 实现并发控制的示例。

class SemaphoreDemo implements Runnable {
    private Semaphore semaphore;
    private int n;

    public SemaphoreDemo(Semaphore semaphore, int n) {
        this.semaphore = semaphore;
        this.n = n;
    }

    @Override
    public void run() {
        try {
            semaphore.acquire(); // 获取一个 permit
            for (int i = 0; i < n; i++) {
                System.out.println(Thread.currentThread().getName() + ": " + i);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            semaphore.release(); // 释放一个 permit
        }
    }
}

测试代码:

public static void main(String[] args) {
    Semaphore semaphore = new Semaphore(2);
    int n = 5;
    for (int i = 0; i < 5; i++) {
        new Thread(new SemaphoreDemo(semaphore, n)).start(); // 同时运行 2 个线程
    }
}

测试结果如下:

解密Java多线程:让线程之间默契无间的通讯和协作技巧

小结

本文介绍了 Java 多线程中的线程通讯和协作技巧。其中,线程通讯主要通过 wait() 和 notify() 方法实现,线程协作主要通过 Semaphore、CountDownLatch 和 CyclicBarrier 等工具类实现。通过代码示例,读者可以更好地理解和应用 Java 多线程。

作者:我崽不熬夜
链接:https://juejin.cn/post/7273433799668711487
来源:稀土掘金

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://itzsg.com/35876.html

(0)

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们YX

mu99908888

在线咨询: 微信交谈

邮件:itzsgw@126.com

工作时间:时刻准备着!

关注微信