如何实现线程之间的通信?如何实现线程池的任务编排?Futrue,信号量, 栅栏等

如何实现线程之间的通信?

如何实现线程池的任务编排?

这两个问题其实一样。

线程通讯的实现方式主要有以下两种:

  • 共享内存:多个线程可以访问同一个共享内存区域,通过读取和写入内存中的数据来进行通讯和同步。
  • 消息传递:多个线程之间通过消息队列、管道、信号量等机制来传递信息和同步状态。

线程通讯的实现方法有以下几种:

  • synchronized + 对象的等待和通知机制:使用 Object 类的 wait() 和 notify() 方法来实现线程之间的通讯。当一个线程需要等待另一个线程执行完某个操作时,它可以调用 wait() 方法使自己进入等待状态,同时释放占有的锁,等待其他线程调用 notify() 或 notifyAll() 方法来唤醒它。被唤醒的线程会重新尝试获取锁并继续执行。
  • 信号量机制:使用 Java 中的 Semaphore 类来实现线程之间的同步和互斥。Semaphore 是一个计数器,用来控制同时访问某个资源的线程数。当某个线程需要访问共享资源时,它必须先从 Semaphore 中获取一个许可证,如果已经没有许可证可用,线程就会被阻塞,直到其他线程释放了许可证。
  • 栅栏机制:使用 Java 中的 CyclicBarrier 类来实现多个线程之间的同步,它允许多个线程在指定的屏障处等待,并在所有线程都达到屏障时继续执行。
  • 锁机制:使用 Java 中的 Lock 接口和 Condition 接口来实现线程之间的同步和互斥。Lock 是一种更高级的互斥机制,它允许多个条件变量(Condition)并支持在同一个锁上等待和唤醒。

1.synchronized + 对象的等待和通知机制

可以参考:https://blog.youkuaiyun.com/weixin_43751710/article/details/105438104

public class WaitNotifyDemo {
    public static void main(String[] args) {
        Object lock = new Object();
        ThreadA threadA = new ThreadA(lock);
        ThreadB threadB = new ThreadB(lock);
        threadA.start();
        threadB.start();
    }
    static class ThreadA extends Thread {
        private Object lock;
        public ThreadA(Object lock) {
            this.lock = lock;
        }
        public void run() {
            synchronized (lock) {
                System.out.println("ThreadA start...");
                try {
                    lock.wait(); // 线程A等待
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("ThreadA end...");
            }
        }
    }
    static class ThreadB extends Thread {
        private Object lock;

        public ThreadB(Object lock) {
            this.lock = lock;
        }
        public void run() {
            synchronized (lock) {
                System.out.println("ThreadB start...");
                lock.notify(); // 唤醒线程A
                System.out.println("ThreadB end...");
            }
        }
    }
}

2.信号量机制

在 Java 中使用 Semaphore 实现信号量,Semaphore 是一个计数器,用来控制同时访问某个资源的线程数。当某个线程需要访问共享资源时,它必须先从 Semaphore 中获取一个许可证,如果已经没有许可证可用,线程就会被阻塞,直到其他线程释放了许可证。它的示例代码如下:

import java.util.concurrent.Semaphore;

public class SemaphoreDemo {
    public static void main(String[] args) {
        Semaphore semaphore = new Semaphore(2);

        for (int i = 0; i < 5; i++) {
            new Thread(new Worker(i, semaphore)).start();
        }
    }

    static class Worker implements Runnable {
        private int id;
        private Semaphore semaphore;

        public Worker(int id, Semaphore semaphore) {
            this.id = id;
            this.semaphore = semaphore;
        }

        @Override
        public void run() {
            try {
                semaphore.acquire();
                System.out.println("Worker " + id + " acquired permit.");
                Thread.sleep(1000);
                System.out.println("Worker " + id + " released permit.");
                semaphore.release();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

3. 栅栏机制

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class CyclicBarrierDemo {
    public static void main(String[] args) {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(3, new Runnable() {
            @Override
            public void run() {
                System.out.println("All threads have reached the barrier.");
            }
        });

        for (int i = 1; i <= 3; i++) {
            new Thread(new Worker(i, cyclicBarrier)).start();
        }
    }

    static class Worker implements Runnable {
        private int id;
        private CyclicBarrier cyclicBarrier;

        public Worker(int id, CyclicBarrier cyclicBarrier) {
            this.id = id;
            this.cyclicBarrier = cyclicBarrier;
        }

        @Override
        public void run() {
            try {
                System.out.println("Worker " + id + " is working.");
                Thread.sleep((long) (Math.random() * 2000));
                System.out.println("Worker " + id + " has reached the barrier.");
                cyclicBarrier.await();
                System.out.println("Worker " + id + " is continuing the work.");
            } catch (InterruptedException | BrokenBarrierException e) {
                e.printStackTrace();
            }
        }
    }
}

4.锁机制

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ConditionDemo {

    private Lock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();
    private volatile boolean flag = false;

    public static void main(String[] args) {
        ConditionDemo demo = new ConditionDemo();
        new Thread(demo::waitCondition).start();
        new Thread(demo::signalCondition).start();
    }

    private void waitCondition() {
        lock.lock();
        try {
            while (!flag) {
                System.out.println(Thread.currentThread().getName() + " is waiting for signal.");
                condition.await();
            }
            System.out.println(Thread.currentThread().getName() + " received signal.");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    private void signalCondition() {
        lock.lock();
        try {
            Thread.sleep(3000); // 模拟等待一段时间后发送信号
            flag = true;
            System.out.println(Thread.currentThread().getName() + " sends signal.");
            condition.signalAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}

原文链接:https://www.javacn.site/interview/thread/thread-communication.html#%E7%AD%89%E5%BE%85%E9%80%9A%E7%9F%A5%E5%AE%9E%E7%8E%B0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值