栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

java多线程实现有序输出ABC

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

java多线程实现有序输出ABC

3个线程,线程1输出A,线程2输出B,线程3输出C,让这个3个线程循环有序地输出ABCABC…

看到这个题目,感觉很有意思,问题的本质是在多线程执行环境,控制线程的执行顺序,实现的方式有非常多种,本质上需要解决Java多线程环境下的线程执行的同步和利用锁机制来控制线程的执行顺序。

方式1:利用synchronized

这种方式也就是使用java内置的monitor机制,配合wait和notifyAll,代码如下:

(1)利用volatile做线程间资源的同步访问,同时作为线程调度的标志;
(2)利用notifyAll来唤醒其他等待当前的monitor资源的线程;

public class ThreadOrderWithSync {

  private volatile int flag = 'A';
  private final static Object LOCK = new Object();

  Runnable a = () -> {
    while (true) {
      synchronized (LOCK) {
 if (flag == 'A' ) {
   System.out.println("A");

   flag = 'B';
   // let other thread race to get the monitor
   LOCK.notifyAll();
 } else {
   try {
     LOCK.wait();
   } catch (InterruptedException e) {
     e.printStackTrace();
   }
 }
      }
    }
  };

  Runnable b = () -> {
    while (true) {
      synchronized (LOCK) {
 if (flag == 'B' ) {
   System.out.println("B");

   flag = 'C';
   // let other thread race to get the monitor
   LOCK.notifyAll();
 } else {
   try {
     LOCK.wait();
   } catch (InterruptedException e) {
     e.printStackTrace();
   }
 }
      }
    }
  };

  Runnable c = () -> {
    while (true) {
      synchronized (LOCK) {
 if (flag == 'C' ) {
   System.out.println("C");

   flag = 'A';
   // let other thread race to get the monitor
   LOCK.notifyAll();
 } else {
   try {
     LOCK.wait();
   } catch (InterruptedException e) {
     e.printStackTrace();
   }
 }
      }
    }
  };

  public void runTest() {
    Thread ta = new Thread(a);
    Thread tb = new Thread(b);
    Thread tc = new Thread(c);

    ta.start();
    tb.start();
    tc.start();
  }

  public static void main(String[] args) {
    ThreadOrderWithSync sync = new ThreadOrderWithSync();
    sync.runTest();
  }
}

方式2:利用并发包ReentrantLock和Condition的锁机制

上面方式1的synchronized机制,因为当前的所有线程都争用同一个monitor资源,因此只能通过notifyAll来通知其他线程来加锁,因此每次都会出现race condition,但是,通过ReentrantLock的Condition,我们可以精确控制,下一个该唤醒signal的线程是哪一个(因为我们知道执行的顺序是A->B->C的循环),相比synchronized的机制,Condition机制可以更精细化线程的调度设计,代码示例如下:


public class ThreadOrderWithCondition {

  private static final ReentrantLock LOCK = new ReentrantLock();
  private static final Condition C_A = LOCK.newCondition();
  private static final Condition C_B = LOCK.newCondition();
  private static final Condition C_C = LOCK.newCondition();

  
  private volatile int flag = 'A';

  Runnable a = () -> {
    while (true) {
      LOCK.lock();

      if (flag == 'A') {
 System.out.println("A");
 flag = 'B';
 // signal B to run
 C_B.signal();
      } else {
 try {
   // block and wait signal to invoke
   C_A.await();
 } catch (InterruptedException e) {
   e.printStackTrace();
 }
      }

      LOCK.unlock();
    }
  };

  Runnable b = () -> {
    while (true) {
      LOCK.lock();

      if (flag == 'B') {
 System.out.println("B");
 flag = 'C';
 // signal C to run
 C_C.signal();
      } else {
 try {
   // block and wait signal to invoke
   C_B.await();
 } catch (InterruptedException e) {
   e.printStackTrace();
 }
      }

      LOCK.unlock();
    }
  };

  Runnable c = () -> {
    while (true) {
      LOCK.lock();

      if (flag == 'C') {
 System.out.println("C");
 flag = 'A';
 // signal A to run
 C_A.signal();
      } else {
 try {
   // block and wait signal to invoke
   C_C.await();
 } catch (InterruptedException e) {
   e.printStackTrace();
 }
      }

      LOCK.unlock();
    }
  };

  public void runTest() {
    Thread threadA = new Thread(a);
    Thread threadB = new Thread(b);
    Thread threadC = new Thread(c);

    threadA.start();
    threadB.start();
    threadC.start();
  }

  public static void main(String[] args) {
    ThreadOrderWithCondition o = new ThreadOrderWithCondition();
    o.runTest();
  }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持考高分网。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/137166.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号