日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

java.util 常见_Java基础知识-java.util.concurrent包下常见类的使用

發布時間:2024/4/19 java 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java.util 常见_Java基础知识-java.util.concurrent包下常见类的使用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一,Condition

一個場景,兩個線程數數,同時啟動兩個線程,線程A數1、2、3,然后線程B數4、5、6,最后線程A數7、8、9,程序結束,這涉及到線程之間的通信。

public classConditionTest {static classNumberWrapper {public int value = 1;

}public static voidmain(String[] args) {//初始化可重入鎖

final Lock lock = newReentrantLock();//第一個條件當屏幕上輸出到3

final Condition reachThreeCondition =lock.newCondition();//第二個條件當屏幕上輸出到6

final Condition reachSixCondition =lock.newCondition();//NumberWrapper只是為了封裝一個數字,一邊可以將數字對象共享,并可以設置為final//注意這里不要用Integer, Integer 是不可變對象

final NumberWrapper num = newNumberWrapper();//初始化A線程

Thread threadA = new Thread(newRunnable() {

@Overridepublic voidrun() {//需要先獲得鎖

lock.lock();

System.out.println("ThreadA獲得lock");try{

System.out.println("threadA start write");//A線程先輸出前3個數

while (num.value <= 3) {

System.out.println(num.value);

num.value++;

}//輸出到3時要signal,告訴B線程可以開始了

reachThreeCondition.signal();

}finally{

lock.unlock();

System.out.println("ThreadA釋放lock");

}

lock.lock();try{//等待輸出6的條件

System.out.println("ThreadA獲得lock");

reachSixCondition.await();

System.out.println("threadA start write");//輸出剩余數字

while (num.value <= 9) {

System.out.println(num.value);

num.value++;

}

}catch(InterruptedException e) {

e.printStackTrace();

}finally{

lock.unlock();

System.out.println("ThreadA釋放lock");

}

}

});

Thread threadB= new Thread(newRunnable() {

@Overridepublic voidrun() {try{

lock.lock();

System.out.println("ThreadB獲得lock");

Thread.sleep(5000);//是await方法釋放了鎖

while (num.value <= 3) {//等待3輸出完畢的信號

reachThreeCondition.await();

}

}catch(InterruptedException e) {

e.printStackTrace();

}finally{

lock.unlock();

System.out.println("ThreadB釋放lock");

}try{

lock.lock();

System.out.println("ThreadB獲得lock");//已經收到信號,開始輸出4,5,6

System.out.println("threadB start write");while (num.value <= 6) {

System.out.println(num.value);

num.value++;

}//4,5,6輸出完畢,告訴A線程6輸出完了

reachSixCondition.signal();

}finally{

lock.unlock();

System.out.println("ThreadB釋放lock");

}

}

});//啟動兩個線程

threadB.start();

threadA.start();

}

}

創建方式:通過Lock創建,Lock.newCondition();

常用方法:

await():阻塞,直到相同的Condition調用了signal方法。

signal():通知。

總結:Condition必須與Lock一起使用(wait()、notify()必須與synchronized一起使用,否則運行會報錯java.lang.IllegalMonitorStateException),相比于wait與notify更加的靈活,可以設置各種情形,如上例中的到達3和到達6兩個條件。

二,CountDownLatch

直接上代碼:

public classCountDownLatchTest {public static voidmain(String[] args) {final CountDownLatch c = new CountDownLatch(3);//總數3

Thread t1 = new Thread(newRunnable(){

@Overridepublic voidrun() {try{

System.out.println("開始等");

c.await();//阻塞,等待countDown,當countDown到0就執行后面的完事了

System.out.println("完事");

}catch(InterruptedException e) {

e.printStackTrace();

}

}

});

Thread t2= new Thread(newRunnable(){

@Overridepublic voidrun() {for(int i=3;i>0;i--){

c.countDown();//減1

}

}

});

t1.start();

t2.start();

}

}

創建方式:直接創建,new CountDownLatch(int num);

常用方法:

await():阻塞,直到countDown方法被執行了num次。

countDown():減

總結:適用于一個線程等待其他線程的情景。

三,CyclicBarrier

通過代碼思考一下與CountDownLatch的區別。

public classMainMission {privateCyclicBarrier barrier;private final static int threadCounts = 5;public voidrunMission() {

ExecutorService exec=Executors.newFixedThreadPool(threadCounts);//new 的時候要傳入數字,我發現,這個類似semaphore,如果位置不足,線程會搶位置。數字要是threadCounts+1為主線程留一個位子,但實際測試中發現,只要等于threadCount就可以

barrier=new CyclicBarrier(threadCounts+1);for(int i=0;i<5;i++){

exec.execute(newMission(barrier));

}try{

barrier.await();

}catch(InterruptedException e) {

e.printStackTrace();

}catch(BrokenBarrierException e) {

e.printStackTrace();

}try{

Thread.sleep(1);

}catch(InterruptedException e) {

e.printStackTrace();

}

System.out.println("所有任務都執行完了");

exec.shutdown();//如果不關閉,程序一直處于運行狀態

}public static voidmain(String[] args) {

MainMission m= newMainMission();

m.runMission();

}

}class Mission implementsRunnable{privateCyclicBarrier barrier;publicMission(CyclicBarrier barrier){this.barrier =barrier;

}

@Overridepublic voidrun() {

System.out.println(Thread.currentThread().getName()+"開始執行任務");try{int sleepSecond = new Random().nextInt(10)*1000;

System.out.println(Thread.currentThread().getName()+"要執行"+sleepSecond+"秒任務");

Thread.sleep(sleepSecond);

}catch(InterruptedException e) {

e.printStackTrace();

}try{

barrier.await();

}catch(InterruptedException e) {

e.printStackTrace();

}catch(BrokenBarrierException e) {

e.printStackTrace();

}

System.out.println(Thread.currentThread().getName()+"執行完畢");

}

}

創建方式:直接創建,new?CyclicBarrier(int num);

常用方法:

await():阻塞,直到阻塞的線程數量達到num個。

總結:想想一下百米跑,所有運動員都就位之后才會發令起跑,線程調用await意味著說,我準備好了。

四,Semaphore

下面是一個上廁所的例子,廁所位置有限,想用得排隊了。實現使用的就是信號量,可以看出信號量可以用來做限流。

public class MySemaphore implementsRunnable{

Semaphore position;private intid;public MySemaphore(inti,Semaphore s){this.id=i;this.position=s;

}

@Overridepublic voidrun() {try{if(position.availablePermits()>0){

System.out.println("顧客["+this.id+"]進入廁所,有空位");

}else{

System.out.println("顧客["+this.id+"]進入廁所,沒空位,排隊");

}

position.acquire();//只有在acquire之后才能真正的獲得了position

System.out.println("#########顧客["+this.id+"]獲得坑位");

Thread.sleep((int)(Math.random()*100000));

System.out.println("@@@@@@@@@顧客["+this.id+"]使用完畢");

position.release();

}catch(Exception e){

e.printStackTrace();

}

}public static voidmain(String args[]){

ExecutorService list=Executors.newCachedThreadPool();

Semaphore position=new Semaphore(2);for(int i=0;i<10;i++){

list.submit(new MySemaphore(i+1,position));

}

list.shutdown();

position.acquireUninterruptibly(2);

System.out.println("使用完畢,需要清掃了");

position.release(2);

}

}

創建方式:直接創建,new Semaphore(int num);

常用方法:

availablePermits():看現在可用的信號量。

acquire():嘗試獲取一個位置,如果獲取不到則阻塞。

release():釋放位置。

acquireUninterruptibly(int num):嘗試獲取num個許可,如果沒有足夠的許可則阻塞,一直阻塞到有足夠的許可釋放出來。調用這個方法的線程具有優先獲取許可的權利。如果調用線程被interrupted,該線程并不會被打斷,它會繼續阻塞等待許可。

總結:搶位置。

五,ReentrantLock

創建方式:

new ReentrantLock(); 此種創建方式會創建出一個非公平鎖。

new ReentrantLock(true); 此種方式會創建出一個公平鎖。

非公平鎖:當鎖處于無線程占有的狀態,此時其他線程和在隊列中等待的線程都可以搶占該鎖。

公平鎖:當鎖處于無線程占有的狀態,在其他線程搶占該鎖的時候,都需要先進入隊列中等待。

tryLock()方法:嘗試去獲取鎖,如果沒有獲取到直接返回,不等待。

六,ReentrantReadWriteLock

創建方式:new ReentrantReadWriteLock();

常用方法:

readLock().lock();寫鎖

writeLock().lock();讀鎖

readLock().unlock();解鎖

writeLock().unlock();解鎖

總結:

* 如果目前是讀鎖,其他讀鎖也可以進請求,寫鎖不能進。

* 如果目前是寫鎖,那么其他所有的鎖都不可以進。

*適用于讀多寫少的情況,如果是寫多讀少用ReentrantLock。

七,Callable接口

*Callable接口支持返回執行結果,此時需要調用FutureTask.get()方法實現,此方法會阻塞主線程直到獲取結果;當不調用此方法時,主線程不會阻塞!

與Runnable對比:

1.Callable可以有返回值,Runnable沒有

2.Callable接口的call()方法允許拋出異常;而Runnable接口的run()方法的異常只能在內部消化,不能繼續上拋;

八,線程池

提供的線程池有幾種:

//有數量限制的線程池

ExecutorService service=Executors.newFixedThreadPool(4);

//沒有數量限制的線程池

ExecutorService service=Executors.newCachedThreadPool();

//單線程池

ExecutorService service=Executors.newSingleThreadExecutor();

他們都是通過下面這個線程池實現的

有數量線程池的實現方式

public static ExecutorService newFixedThreadPool(intnThreads) {return newThreadPoolExecutor(nThreads/*核心線程數*/, nThreads/*最高線程數*/,0L/*高出核心線程數的線程最高存活時間*/, TimeUnit.MILLISECONDS/*高出核心線程數的線程最高存活時間單位*/,new LinkedBlockingQueue()/*任務隊列*/);

猜一猜剩下的兩種線程池是怎么實現的。如果想自己實現,可以自己new

總結

以上是生活随笔為你收集整理的java.util 常见_Java基础知识-java.util.concurrent包下常见类的使用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。