最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java線程通信詳解

 更新時(shí)間:2016年10月26日 17:15:39   作者:趙杰A-124  
本篇文章主要介紹了Java線程通信問題,線程通信用來保證線程協(xié)調(diào)運(yùn)行,有需要的朋友可以了解一下。

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

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

通常利用Objeclt類提供的三個(gè)方法:

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

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

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

示例如下:

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) {
    //實(shí)現(xiàn)兩個(gè)線程輪流對(duì)數(shù)據(jù)進(jìn)行加一操作
    DataWrap dataWrap = new DataWrap();
    
    new ThreadA(dataWrap).start();
    new ThreadB(dataWrap).start();
  }

}

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

示例如下:

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) {
    //實(shí)現(xiàn)兩個(gè)線程輪流對(duì)數(shù)據(jù)進(jìn)行加一操作
    
    DataWrap dataWrap = new DataWrap();
    new ThreadA(dataWrap).start();
    new ThreadB(dataWrap).start();
  }

}

2、使用Condition控制線程通信

當(dāng)使用Lock對(duì)象保證同步時(shí),則使用Condition對(duì)象來保證協(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) {
    //實(shí)現(xiàn)兩個(gè)線程輪流對(duì)數(shù)據(jù)進(jìn)行加一操作
    
    DataWrap dataWrap = new DataWrap();
    new ThreadA(dataWrap).start();
    new ThreadB(dataWrap).start();
  }

}

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

3、使用阻塞隊(duì)列BlockingQueue控制線程通信

BlockingQueue是Queue接口的子接口,主要用來做線程通信使用,它具有一個(gè)特征:當(dāng)生產(chǎn)者線程試圖向BlockingQueue中放入元素時(shí),如果隊(duì)列已滿,則該線程被阻塞;當(dāng)消費(fèi)者線程試圖從BlockingQueue中取出元素時(shí),如果隊(duì)列已空,則該線程被阻塞。這兩個(gè)特征分別對(duì)應(yīng)兩個(gè)支持阻塞的方法,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) {
    ///實(shí)現(xiàn)兩個(gè)線程輪流對(duì)數(shù)據(jù)進(jìn)行加一操作
    
    DataWrap dataWrap = new DataWrap();
    BlockingQueue<DataWrap> blockingQueue = new ArrayBlockingQueue<>(1);
    
    new ThreadA(blockingQueue, "Consumer").start();
    new ThreadB(blockingQueue, dataWrap, "Producer").start();
  }

}

BlockingQueue共有五個(gè)實(shí)現(xiàn)類:

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

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

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

SynchronousQueue 同步隊(duì)列,要求對(duì)該隊(duì)列的存取操作必須是交替進(jìn)行。

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

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論

临沭县| 永嘉县| 本溪市| 曲水县| 炉霍县| 闽清县| 额敏县| 收藏| 海阳市| 宁安市| 霍州市| 松原市| 舟山市| 赫章县| 博爱县| 海淀区| 奈曼旗| 陕西省| 神池县| 桂林市| 武安市| 华阴市| 新兴县| 广水市| 巍山| 建瓯市| 措美县| 舟山市| 武汉市| 安西县| 临颍县| 河西区| 庐江县| 周至县| 贡山| 长葛市| 新安县| 麻栗坡县| 龙胜| 双流县| 商河县|