java三线程循环有序打印ABC

迅雷笔试题:

编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,要求输出结果必须按ABC的顺序显示;如:ABCABC….依次递推。

解决思路:每个线程运行时先检查他依赖的线程是否已完成工作,线程B依赖线程A的完成,线程C依赖线程B和线程A的完成,线程A依赖线程C的完成。如果当前线程依赖的线程没有执行完,则阻塞当前线程直到条件满足再执行。

Condition.await()会使当前线程暂时阻塞,并释放ReentrantLock锁.

Condition.signalAll()会通知激活Condition.await()而阻塞的线程,这时被激活的线程就会继续检查(通过while循环))是否满足条件,如果满足而且再次获得ReentrantLock锁就能继续运行,否则继续等待。

 1 import java.util.concurrent.locks.Condition;
 2 import java.util.concurrent.locks.ReentrantLock;
 3 
 4 public class ThreadDemo implements Runnable {
 5 
 6     private ReentrantLock lock = new ReentrantLock();
 7     private Condition condition = lock.newCondition();
 8     //标记线程A的状态,true为刚执行完。为什么要两个变量?因为只使用一个变量,当线程A执行完后,a为true,B线程就会不停执行
 9     //所以线程B执行要执行必须满足a==true&&a2==true
10     private volatile Boolean a = false, a2 = false;
11     //标记线程B的状态,true为刚执行完。
12     private volatile Boolean b = false;
13     //标记线程C的状态,true为刚执行完。
14     private volatile Boolean c = true;
15 
16     @Override
17     public void run() {
18         String name = Thread.currentThread().getName();
19         lock.lock();
20         //进入临界区
21         try {
22             for (int i = 0; i < 10; i++) {
23                 if (name.equals("B")) {
24                     //只有a和a2同时为true时才打印B,否则阻塞当前线程
25                     while (!a || !a2) {
26                         condition.await();//条件不满足,暂时阻塞线程,暂时释放lock
27                     }
28                     b = true;
29                     a2 = false;
30                 } else if (name.equals("C")) {
31                     while (!a || !b) {
32                         condition.await();
33                     }
34                     c = true;
35                     b = false;
36                 } else if (name.equals("A")) {
37                     while (!c) {
38                         condition.await();
39                     }
40                     a = true;
41                     a2 = true;
42                     b = false;
43                     c = false;
44                 }
45                 System.out.print(name);
46                 condition.signalAll();//通知正在等待的线程,此时有可能已经满足条件
47             }
48         } catch (InterruptedException e) {
49             e.printStackTrace();
50         } finally {
51             lock.unlock();// 记得要释放锁
52         }
53     }
54 
55     public static void main(String[] args) throws InterruptedException {
56         ThreadDemo task = new ThreadDemo();
57         Thread thread1 = new Thread(task);
58         Thread thread2 = new Thread(task);
59         Thread thread3 = new Thread(task);
60         thread1.setName("A");
61         thread2.setName("B");
62         thread3.setName("C");
63         thread1.start();
64         thread2.start();
65         thread3.start();
66     }
67 
68 }

 下面是更简单的实现方法:

 1 import java.util.concurrent.locks.Condition;
 2 import java.util.concurrent.locks.ReentrantLock;
 3 
 4 public class ThreadDemo implements Runnable {
 5 
 6     private ReentrantLock lock = new ReentrantLock();
 7     private Condition condition = lock.newCondition();
 8     private int state = 0;
 9 
10     @Override
11     public void run() {
12         String name = Thread.currentThread().getName();
13         lock.lock();
14         // 进入临界区
15         try {
16             for (int i = 0; i < 10; i++) {
17                 if (name.equals("B")) {
18                     // 只有a和a2同时为true时才打印B,否则阻塞当前线程
19                     while (state % 3 != 1) {
20                         condition.await();// 条件不满足,暂时阻塞线程,暂时释放lock
21                     }
22                 } else if (name.equals("C")) {
23                     while (state % 3 != 2) {
24                         condition.await();
25                     }
26                 } else if (name.equals("A")) {
27                     while (state % 3 != 0) {
28                         condition.await();
29                     }
30                 }
31                 state++;
32                 System.out.print(name);
33                 condition.signalAll();// 通知正在等待的线程,此时有可能已经满足条件
34             }
35         } catch (InterruptedException e) {
36             e.printStackTrace();
37         } finally {
38             lock.unlock();// 记得要释放锁
39         }
40     }
41 
42     public static void main(String[] args) throws InterruptedException {
43         ThreadDemo task = new ThreadDemo();
44         Thread thread1 = new Thread(task);
45         Thread thread2 = new Thread(task);
46         Thread thread3 = new Thread(task);
47         thread1.setName("A");
48         thread2.setName("B");
49         thread3.setName("C");
50         thread1.start();
51         thread2.start();
52         thread3.start();
53     }
54 
55 }
原文地址:https://www.cnblogs.com/JT-L/p/5771455.html