三个线程交替打印的几种实现方式

编程入门 行业动态 更新时间:2024-10-15 14:20:33

三个线程交替打印的<a href=https://www.elefans.com/category/jswz/34/1769370.html style=几种实现方式"/>

三个线程交替打印的几种实现方式

前言

线程的交替打印,实际上涉及的内容是线程间的通信,下面,介绍三种线程间通信实现的交替打印方法和一种非线程间通信的实现方式。

线程通信方式

1、synchronized + wait&notify/notifyAll

synchronized是Java中的一个关键字,用于实现对共享资源的互斥访问。wait和notify/notifyAll是Object类中的两个方法,用于实现线程间的通信。wait方法会让当前线程释放锁,并进入等待状态,直到被其他线程唤醒。notify/notifyAll方法会唤醒一个在同一个锁上等待的线程。我们可以使用一个共享变量a来表示当前应该打印哪个字母,初始值为0。当state为0时,表示轮到A线程打印;当a为1时,表示轮到B线程打印;当a为2时,表示轮到C线程打印。每个线程在打印完字母后,需要将a设置为下一个线程的值,以便循环。同时,每个线程还需要唤醒下一个线程,并让自己进入等待状态。

static class m1{private static int a = 0;private final static Object lock = new Object();public void test(){new Thread(()->{synchronized(lock){while(a != 0){try {lock.wait();} catch (Exception e) {throw new RuntimeException(e);}}System.out.println(Thread.currentThread().getName());a = 1;lock.notifyAll();}},"AAAAAAAAAAAAAA").start();new Thread(()->{synchronized(lock){while(a != 1){try {lock.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}}System.out.println(Thread.currentThread().getName());a = 2;lock.notifyAll();}},"BBBBBBBBBBBBBB").start();new Thread(()->{synchronized(lock){while(a != 2){try {lock.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}}System.out.println(Thread.currentThread().getName());a = 0;lock.notifyAll();}},"CCCCCCCCCCCCCC").start();}}
2、reentrantLock + condition条件

ReentrantLock是Java中的一个类,用于实现可重入的互斥锁,是AQS的一种实现。ConditionReentrantLock中的一个接口,用于实现线程间的条件等待和唤醒。ReentrantLock可以创建多个Condition对象,每个Condition对象可以绑定一个或多个线程,实现对不同线程的精确控制。我们可以使用一个ReentrantLock对象作为锁,同时创建三个Condition对象,分别绑定A、B、C三个线程。每个线程在打印字母之前,需要调用对应的Condition对象的await方法,等待被唤醒。每个线程在打印字母之后,需要调用下一个Condition对象的signal方法,唤醒下一个线程。

static class m2{private static int state = 0;private final static ReentrantLock lock = new ReentrantLock();private final static Condition A = lock.newCondition();private final static Condition B = lock.newCondition();private final static Condition C = lock.newCondition();public void test(){new Thread(()->{lock.lock();try{while(state != 0){A.await();}System.out.println(Thread.currentThread().getName());state = 1;B.signal();}catch (Exception e){e.printStackTrace();}finally {lock.unlock();}},"AAAAAAAAAAAAAA").start();new Thread(()->{lock.lock();try{while(state != 1){B.await();}System.out.println(Thread.currentThread().getName());state = 2;C.signal();}catch (Exception e){e.printStackTrace();}finally {lock.unlock();}},"BBBBBBBBBBBBBB").start();new Thread(()->{lock.lock();try{while(state != 2){C.await();}System.out.println(Thread.currentThread().getName());state = 0;A.signal();}catch (Exception e){e.printStackTrace();}finally {lock.unlock();}},"CCCCCCCCCCCCCC").start();}}
3、Semaphore信号量

Semaphore是Java中的一个类,用于实现信号量机制。信号量是一种计数器,用于控制对共享资源的访问。Semaphore可以创建多个信号量对象,每个信号量对象可以绑定一个或多个线程,实现对不同线程的精确控制。我们可以使用三个Semaphore对象,分别初始化为1、0、0,表示A、B、C三个线程的初始许可数。每个线程在打印字母之前,需要调用对应的Semaphore对象的acquire方法,获取许可。每个线程在打印字母之后,需要调用下一个Semaphore对象的release方法,释放许可。

static class m3{private static final Semaphore A = new Semaphore(1);private static final Semaphore B = new Semaphore(0);private static final Semaphore C = new Semaphore(0);public static void test(){new Thread(()->{try{A.acquire();System.out.println(Thread.currentThread().getName());B.release();} catch (InterruptedException e) {throw new RuntimeException(e);}},"AAAAAAAAAAAAAA").start();new Thread(()->{try{B.acquire();System.out.println(Thread.currentThread().getName());C.release();} catch (InterruptedException e) {throw new RuntimeException(e);}},"BBBBBBBBBBBBBB").start();new Thread(()->{try{C.acquire();System.out.println(Thread.currentThread().getName());A.release();} catch (InterruptedException e) {throw new RuntimeException(e);}},"CCCCCCCCCCCCCC").start();}}

非线程通信方式

通过cas操作

AtomicInteger是Java中的一个类,用于实现原子性的整数操作。CAS是一种无锁的算法,全称为Compare And Swap,即比较并交换。CAS操作需要三个参数:一个内存地址,一个期望值,一个新值。如果内存地址的值与期望值相等,就将其更新为新值,否则不做任何操作。我们可以使用一个AtomicInteger对象来表示当前应该打印哪个字母,初始值为0。当state为0时,表示轮到A线程打印;当state为1时,表示轮到B线程打印;当state为2时,表示轮到C线程打印。每个线程在打印完字母后,需要使用CAS操作将state设置为下一个线程值,以便循环。

public static class m4{private static volatile AtomicInteger state = new AtomicInteger(0);public void test(){new Thread(()->{while(state.get() == 0){System.out.println(Thread.currentThread().getName());statepareAndSet(state.get(), 1);}},"AAAAAAAAAAAAAA").start();new Thread(()->{while(state.get() == 1){System.out.println(Thread.currentThread().getName());statepareAndSet(state.get(), 2);}},"BBBBBBBBBBBBBB").start();new Thread(()->{while(state.get() == 2){System.out.println(Thread.currentThread().getName());statepareAndSet(state.get(), 0);}},"CCCCCCCCCCCCCC").start();}}

更多推荐

三个线程交替打印的几种实现方式

本文发布于:2023-12-07 07:23:06,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1670523.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:几种   线程   方式

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!