欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java多線程通信:交替打印ABAB實例

 更新時間:2020年08月26日 11:40:27   作者:buptmumu  
這篇文章主要介紹了Java多線程通信:交替打印ABAB實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧

使用wait()和notify()實現Java多線程通信:兩個線程交替打印A和B,如ABABAB

public class Test {
  public static void main(String[] args) {
    final PrintAB print = new PrintAB();
    new Thread(new Runnable() {
      public void run(){
        for(int i=0;i<5;i++) {
          print.printA();
          }
          }
    }).start();
    new Thread(new Runnable() {
      public void run() {
        for(int i=0;i<5;i++) {
          print.printB(); }
              }
     }).start();
    }
 }
 class PrintAB{
  private boolean flag = true;
  public synchronized void printA () {
      while(!flag) {
        try {
          this.wait();
        } catch (InterruptedException e) {
          e.printStackTrace();
               } }
        System.out.print("A");
         flag = false;
         this.notify();
      }
  public synchronized void printB () {
      while(flag) {
        try {
          this.wait();
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
      System.out.print("B");
      flag = true;
      this.notify(); }
 }

補充知識:Java多個線程順序打印數字

要求

啟動N個線程, 這N個線程要不間斷按順序打印數字1-N. 將問題簡化為3個線程無限循環(huán)打印1到3

方法一: 使用synchronized

三個線程無序競爭同步鎖, 如果遇上的是自己的數字, 就打印. 這種方式會浪費大量的循環(huán)

public class TestSequential1 {
  private volatile int pos = 1;
  private volatile int count = 0;
 
  public void one(int i) {
    synchronized (this) {
      if (pos == i) {
        System.out.println("T-" + i + " " + count);
        pos = i % 3 + 1;
        count = 0;
      } else {
        count++;
      }
    }
  }
 
  public static void main(String[] args) {
    TestSequential1 demo = new TestSequential1();
    for (int i = 1; i <=3; i++) {
      int j = i;
      new Thread(()->{
        while(true) {
          demo.one(j);
        }
      }).start();
    }
  }
}

輸出

T-1 0
T-2 5793
T-3 5285
T-1 2616
T-2 33
T-3 28
T-1 22
T-2 44
T-3 6
T-1 881
T-2 118358
T-3 247380
T-1 30803
T-2 29627
T-3 52044
...

方法二: 使用synchronized配合wait()和notifyAll()

競爭同步鎖時使用wait()和notifyAll(), 可以避免浪費循環(huán)

public class TestSequential4 {
  private volatile int pos = 1;
  private volatile int count = 0;
  private final Object obj = new Object();
 
  public void one(int i) {
    System.out.println(i + " try");
    synchronized (obj) {
      System.out.println(i + " in");
      try {
        while (pos != i) {
          count++;
          System.out.println(i + " wait");
          obj.wait();
        }
        System.out.println("T-" + i + " " + count);
        pos = i % 3 + 1;
        count = 0;
        obj.notifyAll();
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
  }
 
  public static void main(String[] args) {
    TestSequential4 demo = new TestSequential4();
    for (int i = 3; i >=1; i--) {
      int j = i;
      new Thread(()->{
        while(true) {
          demo.one(j);
        }
      }).start();
    }
  }
}

輸出

3 try
3 in
3 wait
2 try
2 in
2 wait
1 try
1 in
T-1 2
1 try
1 in
1 wait
T-2 1
2 try
2 in
2 wait
T-3 1
3 try
3 in
3 wait
2 wait
T-1 2
1 try
1 in
1 wait
T-2 1
2 try
2 in
2 wait
T-3 1
3 try
3 in
3 wait
2 wait
T-1 2
1 try
1 in
1 wait
T-2 1
2 try
2 in
2 wait
T-3 1
3 try
3 in
3 wait
2 wait
T-1 2
1 try
1 in
1 wait
T-2 1
2 try
2 in
2 wait
T-3 1
3 try
3 in
3 wait
2 wait
T-1 2
1 try
1 in
1 wait
T-2 1
2 try
2 in
2 wait
T-3 1
3 try
3 in
3 wait
2 wait
T-1 2
1 try
1 in
1 wait
T-2 1
2 try
2 in
2 wait
T-3 1
3 try
3 in
3 wait
2 wait
T-1 2
1 try
1 in
1 wait
T-2 1
2 try
2 in
2 wait
T-3 1
3 try
3 in
3 wait
2 wait
T-1 2
1 try
1 in
1 wait
T-2 1
2 try
2 in
2 wait
T-3 1
3 try
3 in
3 wait
2 wait
T-1 2
1 try
1 in
1 wait
T-2 1
2 try
2 in
2 wait
T-3 1
3 try
3 in
3 wait
2 wait
T-1 2
...

方法三: 使用可重入鎖

用Lock做, 非公平鎖, 三個線程競爭, 如果遇上的是自己的數字, 就打印. 這種方式也會浪費大量的循環(huán)

public class TestSequential2 {
  private final Lock lock = new ReentrantLock();
  private volatile int pos = 1;
  private volatile int count = 0;
 
  public void one(int i) {
    lock.lock();
    if (pos == i) {
      System.out.println("T-" + i + " " + count);
      pos = i % 3 + 1;
      count = 0;
    } else {
      count++;
    }
    lock.unlock();
  }
 
  public static void main(String[] args) {
    TestSequential2 demo = new TestSequential2();
    for (int i = 1; i <=3; i++) {
      int j = i;
      new Thread(()->{
        while(true) {
          demo.one(j);
        }
      }).start();
    }
  }
}

輸出

T-1 0
T-2 0
T-3 323
T-1 54
T-2 68964
T-3 97642
T-1 6504
T-2 100603
T-3 6989
T-1 1313
T-2 0
T-3 183741
T-1 233
T-2 5081
T-3 164367
..

方法四: 使用可重入鎖, 啟用公平鎖

和3一樣, 但是使用公平鎖, 這種情況下基本上可以做到順序執(zhí)行, 偶爾會產生多一次循環(huán)

private final Lock lock = new ReentrantLock(true);

輸出

T-1 0
T-2 0
T-3 0
T-1 0
T-2 0
T-3 0
T-1 0
T-2 0
T-3 0
T-1 0
T-2 0
T-3 1
T-1 1
T-2 1
T-3 1
...

方法五: 使用Condition

每個線程如果看到不是自己的計數, 就await(), 如果是自己的計數, 就完成打印動作, 再signalAll()所有其他線程去繼續(xù)運行, 自己在下一個循環(huán)后, 即使又繼續(xù)執(zhí)行, 也會因為計數已經變了而await.

如果ReentrantLock構造參數使用true, 可以基本消除 ~await 這一步的輸出.

public class ReentrantLockCondition2 {
  private static Lock lock = new ReentrantLock();
  private static Condition condition = lock.newCondition();
  private volatile int state = 1;
 
  private void handle(int state) {
    lock.lock();
    try {
      while(true) {
        while(this.state != state) {
          System.out.println(state + " ~await");
          condition.await();
        }
        System.out.println(state);
        this.state = state % 3 + 1;
        condition.signalAll();
        System.out.println(state + " await");
        condition.await();
      }
    } catch (InterruptedException e) {
      e.printStackTrace();
    } finally {
      lock.unlock();
    }
  }
 
  public static void main(String[] args) {
    ReentrantLockCondition2 rlc = new ReentrantLockCondition2();
    new Thread(()->rlc.handle(1)).start();
    new Thread(()->rlc.handle(2)).start();
    new Thread(()->rlc.handle(3)).start();
  }
}

方法六: 使用多個Condition

給每個線程不同的condition. 這個和4的區(qū)別是, 可以用condition.signal()精確地通知對應的線程繼續(xù)執(zhí)行(在對應的condition上await的線程, 可能是多個). 這種情況下是可以多個線程都不unlock鎖的情況下進行協作的. 注意下面的while(true)循環(huán)是在lock.lock()方法內部的.

public class ReentrantLockCondition {
  private static Lock lock = new ReentrantLock();
  private static Condition[] conditions = {lock.newCondition(), lock.newCondition(), lock.newCondition()};
  private volatile int state = 1;
 
  private void handle(int state) {
    lock.lock();
    try {
      while(true) {
        while(this.state != state) {
          conditions[state - 1].await();
        }
        System.out.println(state);
        this.state = state % 3 + 1;
        conditions[this.state - 1].signal();
        conditions[state - 1].await();
      }
    } catch (InterruptedException e) {
      e.printStackTrace();
    } finally {
      lock.unlock();
    }
  }
 
  public static void main(String[] args) {
    ReentrantLockCondition rlc = new ReentrantLockCondition();
    new Thread(()->rlc.handle(1)).start();
    new Thread(()->rlc.handle(2)).start();
    new Thread(()->rlc.handle(3)).start();
  }
}

以上這篇Java多線程通信:交替打印ABAB實例就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • spring整合Quartz框架過程詳解

    spring整合Quartz框架過程詳解

    這篇文章主要介紹了spring整合Quartz框架過程詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-12-12
  • SpringMVC基于阻塞隊列LinkedBlockingQueue的同步長輪詢功能實現詳解

    SpringMVC基于阻塞隊列LinkedBlockingQueue的同步長輪詢功能實現詳解

    這篇文章主要介紹了SpringMVC基于阻塞隊列LinkedBlockingQueue的同步長輪詢功能實現詳解,本文介紹的也是生產者消費者的一種實現,生產者不必是一個始終在執(zhí)行的線程,它可以是一個接口,接受客戶端的請求,向隊列中插入消息,需要的朋友可以參考下
    2023-07-07
  • java實現科學計算器的全過程與代碼

    java實現科學計算器的全過程與代碼

    最近編寫了一個功能較全面的科學計算器,該計算器不僅能進行加、減、乘、除等混合運算,而且能計算sin、cos、tan、log等函數的值,還要具有清零、退格、求倒數、求相反數等功能,這篇文章主要給大家介紹了關于java實現科學計算器的相關資料,需要的朋友可以參考下
    2022-06-06
  • Mybatis省略@Param注解原理分析

    Mybatis省略@Param注解原理分析

    這篇文章主要介紹了Mybatis省略@Param注解原理分析,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • 簡單了解spring bean的循環(huán)引用

    簡單了解spring bean的循環(huán)引用

    這篇文章主要介紹了簡單了解spring bean的循環(huán)引用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-08-08
  • window版 IntelliJ IDEA 快捷鍵圖文教程

    window版 IntelliJ IDEA 快捷鍵圖文教程

    本文通過圖文并茂的形式給大家介紹了window版 IntelliJ IDEA 快捷鍵的操作方法,需要的朋友參考下吧
    2018-02-02
  • Java8新特性:函數式編程

    Java8新特性:函數式編程

    Java8最新引入函數式編程概念,該項技術可以大大提升編碼效率,本文會對涉及的對象等進行兩種方法的對比,對新技術更直白的看到變化,更方便學習
    2021-06-06
  • Java中的HashMap弱引用之WeakHashMap詳解

    Java中的HashMap弱引用之WeakHashMap詳解

    這篇文章主要介紹了Java中的HashMap弱引用之WeakHashMap詳解,當內存空間不足,Java虛擬機寧愿拋出OutOfMemoryError錯誤,使程序異常終止,也不會靠隨意回收具有強引用的對象來解決內存不足的問題,需要的朋友可以參考下
    2023-09-09
  • 詳談HashMap和ConcurrentHashMap的區(qū)別(HashMap的底層源碼)

    詳談HashMap和ConcurrentHashMap的區(qū)別(HashMap的底層源碼)

    下面小編就為大家?guī)硪黄斦凥ashMap和ConcurrentHashMap的區(qū)別(HashMap的底層源碼)。小編覺得挺不錯的,現在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-08-08
  • Eclipse內置瀏覽器打開方法

    Eclipse內置瀏覽器打開方法

    這篇文章主要介紹了Eclipse內置瀏覽器打開方法,需要的朋友可以了解下。
    2017-09-09

最新評論