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

首頁 > 編程 > Java > 正文

java多線程學(xué)習(xí)-java.util.concurrent詳解(二)Semaphore/FutureTask/Exchanger

2019-11-11 05:59:57
字體:
供稿:網(wǎng)友

java多線程學(xué)習(xí)-java.util.concurrent詳解(二)Semaphore/FutureTask/Exchanger

3. Semaphore 

    我們先來學(xué)習(xí)一下JDK1.5 API中關(guān)于這個(gè)類的詳細(xì)介紹: “一個(gè)計(jì)數(shù)信號量。從概念上講,信號量維護(hù)了一個(gè)許可集。如有必要,在許可可用前會(huì)阻塞每一個(gè) acquire(),然后再獲取該許可。每個(gè) release() 添加一個(gè)許可,從而可能釋放一個(gè)正在阻塞的獲取者。但是,不使用實(shí)際的許可對象,Semaphore 只對可用許可的號碼進(jìn)行計(jì)數(shù),并采取相應(yīng)的行動(dòng)。”     我們一般用它來控制某個(gè)對象的線程訪問對象     例如,對于某個(gè)容器,我們規(guī)定,最多只能容納n個(gè)線程同時(shí)操作 使用信號量來模擬實(shí)現(xiàn) 

具體代碼如下(參考 [JCip]) 

import java.util.Collections;  import java.util.HashSet;  import java.util.Set;  import java.util.concurrent.ExecutorService;  import java.util.concurrent.Executors;  import java.util.concurrent.Semaphore;    public class TestSemaphore {        public static void main(String[] args) {          ExecutorService exec = Executors.newCachedThreadPool();          TestSemaphore t = new TestSemaphore();          final BoundedHashSet<String> set = t.getSet();            for (int i = 0; i < 3; i++) {//三個(gè)線程同時(shí)操作add              exec.execute(new Runnable() {                  public void run() {                      try {                          set.add(Thread.currentThread().getName());                      } catch (InterruptedException e) {                          e.PRintStackTrace();                      }                  }              });          }            for (int j = 0; j < 3; j++) {//三個(gè)線程同時(shí)操作remove              exec.execute(new Runnable() {                  public void run() {                      set.remove(Thread.currentThread().getName());                  }              });          }          exec.shutdown();      }        public BoundedHashSet<String> getSet() {          return new BoundedHashSet<String>(2);//定義一個(gè)邊界約束為2的線程      }        class BoundedHashSet<T> {          private final Set<T> set;          private final Semaphore semaphore;            public BoundedHashSet(int bound) {              this.set = Collections.synchronizedSet(new HashSet<T>());              this.semaphore = new Semaphore(bound, true);          }            public void add(T o) throws InterruptedException {              semaphore.acquire();//信號量控制可訪問的線程數(shù)目              set.add(o);              System.out.printf("add:%s%n",o);          }            public void remove(T o) {              if (set.remove(o))                  semaphore.release();//釋放掉信號量              System.out.printf("remove:%s%n",o);          }      }  }   總結(jié):Semaphore通常用于對象池的控制 

4.FutureTask     我們先來學(xué)習(xí)一下JDK1.5 API中關(guān)于這個(gè)類的詳細(xì)介紹:     “取消的異步計(jì)算。利用開始和取消計(jì)算的方法、查詢計(jì)算是否完成的方法和獲取計(jì)算結(jié)果的方法,此類提供了對 Future 的基本實(shí)現(xiàn)。僅在計(jì)算完成時(shí)才能獲取結(jié)果;如果計(jì)算尚未完成,則阻塞 get 方法。一旦計(jì)算完成,就不能再重新開始或取消計(jì)算。 可使用 FutureTask 包裝 Callable 或 Runnable 對象。因?yàn)?FutureTask 實(shí)現(xiàn)了 Runnable,所以可將 FutureTask 提交給 Executor 執(zhí)行。 除了作為一個(gè)獨(dú)立的類外,此類還提供了 protected 功能,這在創(chuàng)建自定義任務(wù)類時(shí)可能很有用。 “     應(yīng)用舉例:我們的算法中有一個(gè)很耗時(shí)的操作,在編程的是,我們希望將它獨(dú)立成一個(gè)模塊,調(diào)用的時(shí)候當(dāng)做它是立刻返回的,并且可以隨時(shí)取消的 具體代碼如下(參考 [JCIP]) 

import java.util.concurrent.Callable;  import java.util.concurrent.ExecutionException;  import java.util.concurrent.ExecutorService;  import java.util.concurrent.Executors;  import java.util.concurrent.FutureTask;    public class TestFutureTask {        public static void main(String[] args) {          ExecutorService exec=Executors.newCachedThreadPool();                    FutureTask<String> task=new FutureTask<String>(new Callable<String>(){//FutrueTask的構(gòu)造參數(shù)是一個(gè)Callable接口              @Override              public String call() throws Exception {                  return Thread.currentThread().getName();//這里可以是一個(gè)異步操作              }});                            try {                  exec.execute(task);//FutureTask實(shí)際上也是一個(gè)線程                  String result=task.get();//取得異步計(jì)算的結(jié)果,如果沒有返回,就會(huì)一直阻塞等待                  System.out.printf("get:%s%n",result);              } catch (InterruptedException e) {                  e.printStackTrace();              } catch (ExecutionException e) {                  e.printStackTrace();              }      }    }  總結(jié):FutureTask其實(shí)就是新建了一個(gè)線程單獨(dú)執(zhí)行,使得線程有一個(gè)返回值,方便程序的編寫

5. Exchanger     我們先來學(xué)習(xí)一下JDK1.5 API中關(guān)于這個(gè)類的詳細(xì)介紹:     “可以在pair中對元素進(jìn)行配對和交換的線程的同步點(diǎn)。每個(gè)線程將條目上的某個(gè)方法呈現(xiàn)給 exchange 方法,與伙伴線程進(jìn)行匹配,并且在返回時(shí)接收其伙伴的對象。Exchanger 可能被視為 SynchronousQueue 的雙向形式。Exchanger 可能在應(yīng)用程序(比如遺傳算法和管道設(shè)計(jì))中很有用。 “     應(yīng)用舉例:有兩個(gè)緩存區(qū),兩個(gè)線程分別向兩個(gè)緩存區(qū)fill和take,當(dāng)且僅當(dāng)一個(gè)滿了,兩個(gè)緩存區(qū)交換     代碼如下(參考了網(wǎng)上給的示例   http://hi.baidu.com/webidea/blog/item/2995e731e53ad5a55fdf0e7d.html) 

import java.util.ArrayList;  import java.util.concurrent.Exchanger;    public class TestExchanger {        public static void main(String[] args) {          final Exchanger<ArrayList<Integer>> exchanger = new Exchanger<ArrayList<Integer>>();          final ArrayList<Integer> buff1 = new ArrayList<Integer>(10);          final ArrayList<Integer> buff2 = new ArrayList<Integer>(10);            new Thread(new Runnable() {              @Override              public void run() {                  ArrayList<Integer> buff = buff1;                  try {                      while (true) {                          if (buff.size() >= 10) {                              buff = exchanger.exchange(buff);//開始跟另外一個(gè)線程交互數(shù)據(jù)                              System.out.println("exchange buff1");                              buff.clear();                          }                          buff.add((int)(Math.random()*100));                          Thread.sleep((long)(Math.random()*1000));                      }                  } catch (InterruptedException e) {                      e.printStackTrace();                  }              }          }).start();                    new Thread(new Runnable(){              @Override              public void run() {                  ArrayList<Integer> buff=buff2;                  while(true){                      try {                          for(Integer i:buff){                              System.out.println(i);                          }                          Thread.sleep(1000);                          buff=exchanger.exchange(buff);//開始跟另外一個(gè)線程交換數(shù)據(jù)                          System.out.println("exchange buff2");                      } catch (InterruptedException e) {                          e.printStackTrace();                      }                  }              }}).start();      }  }  總結(jié):Exchanger在特定的使用場景比較有用(兩個(gè)伙伴線程之間的數(shù)據(jù)交互) 


發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 重庆市| 玛沁县| 固镇县| 文山县| 新乡市| 上犹县| 祁门县| 东乌| 岐山县| 嘉定区| 涿鹿县| 灌云县| 孝义市| 河曲县| 历史| 曲松县| 化州市| 洪泽县| 汨罗市| 林西县| 玉林市| 安国市| 桃源县| 肥东县| 武宣县| 南丰县| 梁河县| 通榆县| 福建省| 广水市| 镇康县| 新乡县| 大安市| 芦山县| 巨野县| 乌恰县| 宁武县| 丰原市| 七台河市| 年辖:市辖区| 万宁市|