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

Java多線程通信:交替打印ABAB實(shí)例

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

使用wait()和notify()實(shí)現(xiàn)Java多線程通信:兩個(gè)線程交替打印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(); }
 }

補(bǔ)充知識(shí):Java多個(gè)線程順序打印數(shù)字

要求

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

方法一: 使用synchronized

三個(gè)線程無序競(jìng)爭(zhēng)同步鎖, 如果遇上的是自己的數(shù)字, 就打印. 這種方式會(huì)浪費(fèi)大量的循環(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()

競(jìng)爭(zhēng)同步鎖時(shí)使用wait()和notifyAll(), 可以避免浪費(fèi)循環(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做, 非公平鎖, 三個(gè)線程競(jìng)爭(zhēng), 如果遇上的是自己的數(shù)字, 就打印. 這種方式也會(huì)浪費(fèi)大量的循環(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ì)產(chǎn)生多一次循環(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

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

如果ReentrantLock構(gòu)造參數(shù)使用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();
  }
}

方法六: 使用多個(gè)Condition

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

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實(shí)例就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • spring整合Quartz框架過程詳解

    spring整合Quartz框架過程詳解

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

    SpringMVC基于阻塞隊(duì)列LinkedBlockingQueue的同步長(zhǎng)輪詢功能實(shí)現(xiàn)詳解

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

    java實(shí)現(xiàn)科學(xué)計(jì)算器的全過程與代碼

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

    Mybatis省略@Param注解原理分析

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

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

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

    window版 IntelliJ IDEA 快捷鍵圖文教程

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

    Java8新特性:函數(shù)式編程

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

    Java中的HashMap弱引用之WeakHashMap詳解

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

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

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

    Eclipse內(nèi)置瀏覽器打開方法

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

最新評(píng)論