• 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 }
  • 相关阅读:
    使用递归方式判断某个字串是否是回文( palindrome )
    方法的动手动脑
    设计统计英文字母出现频率的感想
    原码、补码、反码
    java语法基础报告
    人月神话阅读笔记01
    第六周学习进度报告--(大二下)
    第五周学习进度报告--(大二下)
    梦断代码阅读笔记03
    个人作业--数组之首尾相连
  • 原文地址:https://www.cnblogs.com/JT-L/p/5771455.html
Copyright © 2020-2023  润新知