多线程交替顺序打印ABC的多种方式

瑞星  金牌会员 | 2024-10-21 09:51:52 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 859|帖子 859|积分 2577

口试题:有 3 个独立的线程,一个只会输出 A,一个只会输出 B,一个只会输出 C,在三个线程启动的情况下,请用合理的方式让他们按顺序打印 ABC。
使用lock,Condition
  1. import java.util.concurrent.locks.Condition;
  2. import java.util.concurrent.locks.Lock;
  3. import java.util.concurrent.locks.ReentrantLock;
  4. public class ABC {
  5.     //可重入锁
  6.     private final static Lock lock = new ReentrantLock();
  7.     //判断是否执行:1表示应该A执行,2表示应该B执行,3表示应该C执行
  8.     private static int state = 1;
  9.     //condition对象
  10.     private static Condition a = lock.newCondition();
  11.     private static Condition b = lock.newCondition();
  12.     private static Condition c = lock.newCondition();
  13.     public static void printA() {
  14.         //通过循环,hang住线程
  15.         for (int i = 0; i < 10; i++) {
  16.             try {
  17.                 //获取锁
  18.                 lock.lock();
  19.                 //并发情况下,不能用if,要用循环判断等待条件,避免虚假唤醒
  20.                 while (state != 1) {
  21.                     a.await();
  22.                 }
  23.                 System.out.print("A");
  24.                 state = 2;
  25.                 b.signal();
  26.             } catch (InterruptedException e) {
  27.                 e.printStackTrace();
  28.             } finally {
  29.                 //要保证不执行的时候,锁能释放掉
  30.                 lock.unlock();
  31.             }
  32.         }
  33.     }
  34.     public static void printB() throws InterruptedException {
  35.         for (int i = 0; i < 10; i++) {
  36.             try {
  37.                 lock.lock();
  38.                 //获取到锁,应该执行
  39.                 while (state != 2) {
  40.                     b.await();
  41.                 }
  42.                 System.out.print("B");
  43.                 state = 3;
  44.                 c.signal();
  45.             } finally {
  46.                 lock.unlock();
  47.             }
  48.         }
  49.     }
  50.     public static void printC() throws InterruptedException {
  51.         for (int i = 0; i < 10; i++) {
  52.             try {
  53.                 lock.lock();
  54.                 while (state != 3) {
  55.                     c.await();
  56.                 }
  57.                 //获取到锁,应该执行
  58.                 System.out.print("C");
  59.                 state = 1;
  60.                 a.signal();
  61.             } finally {
  62.                 lock.unlock();
  63.             }
  64.         }
  65.     }
  66.     public static void main(String[] args) {
  67.         new Thread(new Runnable() {
  68.             @Override
  69.             public void run() {
  70.                 ABC.printA();
  71.             }
  72.         }, "A").start();
  73.         new Thread(new Runnable() {
  74.             @Override
  75.             public void run() {
  76.                 try {
  77.                     ABC.printB();
  78.                 } catch (InterruptedException e) {
  79.                     e.printStackTrace();
  80.                 }
  81.             }
  82.         }, "B").start();
  83.         new Thread(new Runnable() {
  84.             @Override
  85.             public void run() {
  86.                 try {
  87.                     ABC.printC();
  88.                 } catch (InterruptedException e) {
  89.                     e.printStackTrace();
  90.                 }
  91.             }
  92.         }, "C").start();
  93.     }
  94. }
复制代码
使用AtomicInteger
  1. import java.util.concurrent.atomic.AtomicInteger;
  2. public class ABC2 {
  3.     private static AtomicInteger state = new AtomicInteger(1);
  4.     public static void printA() {
  5.         for (int i = 0; i < 10; i++) {
  6.             while (true) {
  7.                 if (state.get() == 1) {
  8.                     System.out.print("A");
  9.                     state.incrementAndGet();
  10.                     break;
  11.                 }
  12.             }
  13.         }
  14.     }
  15.     public static void printB() {
  16.         for (int i = 0; i < 10; i++) {
  17.             while (true) {
  18.                 if (state.get() == 2) {
  19.                     System.out.print("B");
  20.                     state.incrementAndGet();
  21.                     break;
  22.                 }
  23.             }
  24.         }
  25.     }
  26.     public static void printC() {
  27.         for (int i = 0; i < 10; i++) {
  28.             while (true) {
  29.                 if (state.get() == 3) {
  30.                     System.out.print("C");
  31.                     state.set(1);
  32.                     break;
  33.                 }
  34.             }
  35.         }
  36.     }
  37.     public static void main(String[] args) {
  38.         new Thread(new Runnable() {
  39.             @Override
  40.             public void run() {
  41.                 ABC2.printA();
  42.             }
  43.         }, "A").start();
  44.         new Thread(new Runnable() {
  45.             @Override
  46.             public void run() {
  47.                 ABC2.printB();
  48.             }
  49.         }, "B").start();
  50.         new Thread(new Runnable() {
  51.             @Override
  52.             public void run() {
  53.                 ABC2.printC();
  54.             }
  55.         }, "C").start();
  56.     }
  57. }
复制代码
使用LockSupprt

线程阻塞叫醒类-LockSupport详解
  1. public class ABC3 {
  2.     private static Thread t1, t2, t3;
  3.     public static void main(String[] args) {
  4.         t1 = new Thread(() -> {
  5.             for (int i = 0; i < 2; i++) {
  6.                 LockSupport.park();
  7.                 System.out.print("A");
  8.                 LockSupport.unpark(t2);
  9.             }
  10.         });
  11.         t2 = new Thread(() -> {
  12.             for (int i = 0; i < 2; i++) {
  13.                 LockSupport.park();
  14.                 System.out.print("B");
  15.                 LockSupport.unpark(t3);
  16.             }
  17.         });
  18.         t3 = new Thread(() -> {
  19.             for (int i = 0; i < 2; i++) {
  20.                 LockSupport.park();
  21.                 System.out.print("C");
  22.                 LockSupport.unpark(t1);
  23.             }
  24.         });
  25.         t1.start();
  26.         t2.start();
  27.         t3.start();
  28.         // 主线程稍微等待一下,确保其他线程已经启动并且进入park状态。
  29.         try {
  30.             Thread.sleep(100);
  31.         } catch (InterruptedException e) {
  32.             e.printStackTrace();
  33.         }
  34.         // 启动整个流程
  35.         LockSupport.unpark(t1);
  36.     }
  37. }
复制代码
口试题专栏

Java口试题专栏已上线,接待访问。

  • 如果你不知道简历怎么写,简历项目不知道怎么包装;
  • 如果简历中有些内容你不知道该不该写上去;
  • 如果有些综合性题目你不知道怎么答;
那么可以私信我,我会尽我所能帮助你。
关于作者

来自一线程序员Seven的探索与实践,持续学习迭代中~
本文已收录于我的个人博客:https://www.seven97.top
公众号:seven97,接待关注~

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

瑞星

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表