国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

Java線程通信詳解

2019-11-26 13:39:17
字體:
供稿:網(wǎng)友

線程通信用來保證線程協(xié)調(diào)運行,一般在做線程同步的時候才需要考慮線程通信的問題。

1、傳統(tǒng)的線程通信

通常利用Objeclt類提供的三個方法:

  1. wait() 導致當前線程等待,并釋放該同步監(jiān)視器的鎖定,直到其它線程調(diào)用該同步監(jiān)視器的notify()或者notifyAll()方法喚醒線程。
  2. notify(),喚醒在此同步監(jiān)視器上等待的線程,如果有多個會任意選擇一個喚醒
  3. notifyAll() 喚醒在此同步監(jiān)視器上等待的所有線程,這些線程通過調(diào)度競爭資源后,某個線程獲取此同步監(jiān)視器的鎖,然后得以運行。

這三個方法必須由同步監(jiān)視器對象調(diào)用,分為兩張情況:

同步方法時,由于同步監(jiān)視器為this對象,所以可以直接調(diào)用這三個方法。

示例如下:

public class SyncMethodThreadCommunication {  static class DataWrap{    int data = 0;    boolean flag = false;        public synchronized void addThreadA(){      if (flag) {        try {          wait();        } catch (InterruptedException e) {          e.printStackTrace();        }      }             data++;      System.out.println(Thread.currentThread().getName() + " " + data);      flag = true;      notify();    }        public synchronized void addThreadB() {      if (!flag) {        try {          wait();        } catch (InterruptedException e) {          e.printStackTrace();        }      }             data++;      System.out.println(Thread.currentThread().getName() + " " + data);      flag = false;      notify();    }  }    static class ThreadA extends Thread {    private DataWrap data;        public ThreadA(DataWrap dataWrap) {      this.data = dataWrap;    }        @Override    public void run() {      for (int i = 0; i < 10; i++) {        data.addThreadA();      }    }  }    static class ThreadB extends Thread {    private DataWrap data;        public ThreadB(DataWrap dataWrap) {      this.data = dataWrap;    }        @Override    public void run() {      for (int i = 0; i < 10; i++) {        data.addThreadB();      }    }  }    public static void main(String[] args) {    //實現(xiàn)兩個線程輪流對數(shù)據(jù)進行加一操作    DataWrap dataWrap = new DataWrap();        new ThreadA(dataWrap).start();    new ThreadB(dataWrap).start();  }}

同步代碼塊時,需要使用監(jiān)視器對象調(diào)用這三個方法。

示例如下:

public class SyncBlockThreadComminication {  static class DataWrap{    boolean flag;    int data;  }    static class ThreadA extends Thread{    DataWrap dataWrap;        public ThreadA(DataWrap dataWrap){      this.dataWrap = dataWrap;    }        @Override    public void run() {      for(int i = 0 ; i < 10; i++) {        synchronized (dataWrap) {          if (dataWrap.flag) {            try {              dataWrap.wait();            } catch (InterruptedException e) {              e.printStackTrace();            }          }                    dataWrap.data++;          System.out.println(getName() + " " + dataWrap.data);          dataWrap.flag = true;          dataWrap.notify();        }        }    }  }    static class ThreadB extends Thread{    DataWrap dataWrap;        public ThreadB(DataWrap dataWrap){      this.dataWrap = dataWrap;    }        @Override    public void run() {      for (int i = 0; i < 10; i++) {          synchronized (dataWrap) {            if (!dataWrap.flag) {              try {                dataWrap.wait();              } catch (InterruptedException e) {                e.printStackTrace();              }            }                        dataWrap.data++;            System.out.println(getName() + " " + dataWrap.data);            dataWrap.flag = false;            dataWrap.notify();          }        }        }        }  public static void main(String[] args) {    //實現(xiàn)兩個線程輪流對數(shù)據(jù)進行加一操作        DataWrap dataWrap = new DataWrap();    new ThreadA(dataWrap).start();    new ThreadB(dataWrap).start();  }}

2、使用Condition控制線程通信

當使用Lock對象保證同步時,則使用Condition對象來保證協(xié)調(diào)。

示例如下:

import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;import com.sun.media.sound.RIFFInvalidDataException;import javafx.scene.chart.PieChart.Data;public class SyncLockThreadCommunication {  static class DataWrap {    int data;    boolean flag;        private final Lock lock = new ReentrantLock();    private final Condition condition = lock.newCondition();        public void addThreadA() {      lock.lock();      try {        if (flag) {          try {            condition.await();          } catch (InterruptedException e) {            e.printStackTrace();          }        }                data++;        System.out.println(Thread.currentThread().getName() + " " + data);        flag = true;        condition.signal();      } finally {        lock.unlock();      }    }        public void addThreadB() {      lock.lock();      try {        if (!flag) {          try {            condition.await();          } catch (InterruptedException e) {            e.printStackTrace();          }        }                data++;        System.out.println(Thread.currentThread().getName() + " " + data);        flag = false;        condition.signal();      } finally {        lock.unlock();      }    }  }    static class ThreadA extends Thread{    DataWrap dataWrap;        public ThreadA(DataWrap dataWrap) {      this.dataWrap = dataWrap;    }        @Override    public void run() {      for (int i = 0; i < 10; i++) {        dataWrap.addThreadA();      }    }  }    static class ThreadB extends Thread{    DataWrap dataWrap;        public ThreadB(DataWrap dataWrap) {      this.dataWrap = dataWrap;    }        @Override    public void run() {      for (int i = 0; i < 10; i++) {        dataWrap.addThreadB();      }    }  }    public static void main(String[] args) {    //實現(xiàn)兩個線程輪流對數(shù)據(jù)進行加一操作        DataWrap dataWrap = new DataWrap();    new ThreadA(dataWrap).start();    new ThreadB(dataWrap).start();  }}

其中Condition對象的await(), singal(),singalAll()分別對應wait(),notify()和notifyAll()方法。

3、使用阻塞隊列BlockingQueue控制線程通信

BlockingQueue是Queue接口的子接口,主要用來做線程通信使用,它具有一個特征:當生產(chǎn)者線程試圖向BlockingQueue中放入元素時,如果隊列已滿,則該線程被阻塞;當消費者線程試圖從BlockingQueue中取出元素時,如果隊列已空,則該線程被阻塞。這兩個特征分別對應兩個支持阻塞的方法,put(E e)和take()

示例如下:

import java.util.concurrent.ArrayBlockingQueue;import java.util.concurrent.BlockingQueue;public class BlockingQueueThreadComminication {  static class DataWrap{    int data;  }    static class ThreadA extends Thread{    private BlockingQueue<DataWrap> blockingQueue;        public ThreadA(BlockingQueue<DataWrap> blockingQueue, String name) {      super(name);      this.blockingQueue = blockingQueue;    }        @Override    public void run() {      for (int i = 0; i < 100; i++) {        try {          DataWrap dataWrap = blockingQueue.take();                    dataWrap.data++;          System.out.println(getName() + " " + dataWrap.data);          sleep(1000);        } catch (InterruptedException e) {          e.printStackTrace();        }      }    }  }    static class ThreadB extends Thread{    private BlockingQueue<DataWrap> blockingQueue;    private DataWrap dataWrap;        public ThreadB(BlockingQueue<DataWrap> blockingQueue, DataWrap dataWrap, String name) {      super(name);      this.blockingQueue = blockingQueue;      this.dataWrap = dataWrap;    }        @Override    public void run() {      for (int i = 0; i < 100; i++) {        try {          dataWrap.data++;          System.out.println(getName() + " " + dataWrap.data);          blockingQueue.put(dataWrap);          sleep(1000);        } catch (InterruptedException e) {          e.printStackTrace();        }      }    }  }    public static void main(String[] args) {    ///實現(xiàn)兩個線程輪流對數(shù)據(jù)進行加一操作        DataWrap dataWrap = new DataWrap();    BlockingQueue<DataWrap> blockingQueue = new ArrayBlockingQueue<>(1);        new ThreadA(blockingQueue, "Consumer").start();    new ThreadB(blockingQueue, dataWrap, "Producer").start();  }}

BlockingQueue共有五個實現(xiàn)類:

ArrayBlockingQueue 基于數(shù)組實現(xiàn)的BlockingQueue隊列

LinkedBlockingQueue 基于鏈表實現(xiàn)的BlockingQueue隊列

PriorityBlockingQueue 中元素需實現(xiàn)Comparable接口,其中元素的排序是按照Comparator進行的定制排序。

SynchronousQueue 同步隊列,要求對該隊列的存取操作必須是交替進行。

DelayQueue 集合元素必須實現(xiàn)Delay接口,隊列中元素排序按照Delay接口方法getDelay()的返回值進行排序。

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 吉安市| 龙州县| 克拉玛依市| 互助| 和硕县| 巴林右旗| 伊金霍洛旗| 延津县| 泰州市| 丹阳市| 武山县| 田东县| 延吉市| 安宁市| 报价| 卫辉市| 宜城市| 化德县| 丰台区| 临汾市| 行唐县| 德格县| 黑水县| 冕宁县| 商河县| 咸宁市| 都安| 陆丰市| 调兵山市| 泽普县| 通山县| 化德县| 曲阜市| 神木县| 阿图什市| 甘泉县| 衢州市| 原平市| 泸水县| 鹤峰县| 台江县|