CyclicBarrier、CountDownLatch、Callable、FutureTask、thread.join() 、wait()、notify()、Condition

CyclicBarrier使用:java

import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
/**
 * 三個運動員各自準備,等到三我的都準備好後,再一塊兒跑</br>@see    1:先建立一個公共 CyclicBarrier 對象,設置 同時等待 的線程數,CyclicBarrier cyclicBarrier = new CyclicBarrier(3);</br>
    2:這些線程同時開始本身作準備,自身準備完畢後,須要等待別人準備完畢,這時調用 cyclicBarrier.await(); 便可開始等待別人;</br>
    3:當指定的 同時等待 的線程數都調用了 cyclicBarrier.await();時,意味着這些線程都準備完畢好,而後這些線程才 同時繼續執行。</br>
 *
 */
public class TestCyclicBarrier {

    public static void main(String[] args) {
        int runner = 3;
        final CyclicBarrier cycliBarrier = new CyclicBarrier(runner);
        final Random random = new Random();
        
        for (char runnerName = 'A'; runnerName <= 'C'; runnerName++) {
            final String rName = String.valueOf(runnerName);
            new Thread(new Runnable(){
                @Override
                public void run() {
                    long prepareTime = random.nextInt(10000)+100;
                    System.out.println(rName + " is preparing for time: " + prepareTime);
                    try {
                        Thread.sleep(prepareTime);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(rName + " is prepared, waiting for others");
                    try {
                        cycliBarrier.await(); // 當前運動員準備完畢,等待別人準備好
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (BrokenBarrierException e) {
                        e.printStackTrace();
                    }
                    System.out.println(rName + " starts running"); // 全部運動員都準備好了,一塊兒開始跑
                }
                
            }).start();
        }
    }

}

輸出:緩存

CountDownLatch例子dom

import java.util.concurrent.CountDownLatch;
/**
 * 四個線程 A B C D,其中 D 要等到 A B C 全執行完畢後才執行,並且 A B C 是同步運行的@see 1:建立一個計數器,設置初始值,CountdownLatch countDownLatch = new CountDownLatch(2);</br>
    2:在 等待線程 裏調用 countDownLatch.await() 方法,進入等待狀態,直到計數值變成 0;</br>
    3:在 其餘線程 裏,調用 countDownLatch.countDown() 方法,該方法會將計數值減少 1;</br>
    4:當 其餘線程 的 countDown() 方法把計數值變成 0 時,等待線程 裏的 countDownLatch.await() 當即退出,繼續執行下面的代碼。</br>
 *
 */
public class TestCountDownLatch {

    public static void main(String[] args) {
        int workerNum = 3;
        final CountDownLatch countDownlatch = new CountDownLatch(workerNum);
        
        new Thread(new Runnable(){
            @Override
            public void run() {
                System.out.println("D is waiting for other three threads");
                try {
                    countDownlatch.await();
                    System.out.println("D is start work");
                    Thread.sleep(100);
                    System.out.println("D finsh Work");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
        
        for (char threadName = 'A'; threadName <= 'C'; threadName++) {
            final String tName = String.valueOf(threadName);
            new Thread(new Runnable(){
                @Override
                public void run() {
                    System.out.println(tName + " is working");
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(tName + " finished");
                    countDownlatch.countDown();
                }
            }).start();
        }
    }

}

輸出:ide

FutureTask、Callable例子spa

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
/**
 * 咱們想讓子線程去計算從 1 加到 100,並把算出的結果返回到主線程</br>
 * @see
 *     如何把子線程的結果回傳回來呢?在 Java 裏,有一個類是配合 Callable 使用的:FutureTask,不過注意,它獲取結果的 get 方法會阻塞主線程。
 *
 */
public class TestCallableAndFutureTask {

    public static void main(String[] args) {
        Callable<Integer> callAble = new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                System.out.println("Task starts");
                Thread.sleep(100);
                int result = 0;
                for (int i = 0; i <= 100; i++) {
                    result += i;
                }
                System.out.println("Task finished and return result");
                return result;
            }
        };
        
        FutureTask<Integer> futureTask = new FutureTask<Integer>(callAble);
        new Thread(futureTask).start();
        
        try {
            System.out.println("Before futureTask.get()");
            System.out.println("Result: " + futureTask.get());
            System.out.println("After futureTask.get()");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }

}

 輸出:線程

 thread.join()  例子3d

/**
 * 實現效果:線程B在線程A完成以後再執行
 * thread.join() 
 *
 */
public class TestThreadJoin {

    public static void main(String[] args) {
        demo1();
    }
    
    private static void demo1() {
        final Thread A = new Thread(new Runnable(){

            @Override
            public void run() {
                PrintNumber("A");
            }
            
        }) ;
        
        Thread B = new Thread(new Runnable(){

            @Override
            public void run() {
                System.out.println("B 開始等待A");
                try {
                    A.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                PrintNumber("B");
            }
            
        }) ;
        A.start();
        B.start();
    }
    
    private static void PrintNumber(String ThreadName) {
        int i = 0;
        while (i++ < 3) {
            try {
                Thread.sleep(100);
            } catch(InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(ThreadName + " print: " + i);
        }
    }
}

輸出:code

wait()、notify() 例子:對象

public class TestWaitAndnotify {

    public static void main(String[] args) {
        demo2();
    }
    
    public static void demo2 () {
        final Object lock = new Object();
        Thread A = new Thread(new Runnable(){

            @Override
            public void run() {
                System.out.println("INFO: A 等待鎖 ");
                synchronized (lock) {
                    System.out.println("INFO: A 獲得了鎖 lock");
                    System.out.println("A1");
                    try {
                        System.out.println("INFO: A 準備進入等待狀態,放棄鎖 lock 的控制權 ");
                        lock.wait();//掛起線程A 放棄鎖 lock 的控制權
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("INFO: 有人喚醒了 A, A 從新得到鎖 lock");
                    System.out.println("A2");
                    System.out.println("A3");
                }
            }
        });
        
        Thread B = new Thread(new Runnable() {

            @Override
            public void run() {
                 System.out.println("INFO: B 等待鎖 ");
                synchronized (lock) {
                    System.out.println("INFO: B 獲得了鎖 lock");
                    System.out.println("B1");
                    System.out.println("B2");
                    System.out.println("B3");
                    System.out.println("INFO: B 打印完畢,調用 notify 方法 ");
                    lock.notify(); // notify()方法喚醒正在等待lock鎖的線程A
                    System.out.println("線程 B do notify method 完畢");
                }
            }
        });
        
        A.start();
        B.start();
    } 
}

輸出:blog

 Condition 例子(生產消費):

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class TestCondition {
    
    public static void main(String[] args) {  
        final BoundedBuffer b = new BoundedBuffer();  
        
        new Thread(new Runnable() {    // 寫線程
            public void run() {  
                int i = 1;  
                while (true) {  
                    try {  
                        b.put(i++);  
                    } catch (InterruptedException e) {  
                        e.printStackTrace();  
                    }  
                }  
            }
        }).start(); 
        
        new Thread(new Runnable() {  // 讀線程
            public void run() {  
                while (true) {  
                    try {  
                        b.take();  
                    } catch (InterruptedException e) {  
                        e.printStackTrace();  
                    }  
                }  
            }  
        }).start();  
    }
}
class BoundedBuffer{
    final Lock lock = new ReentrantLock();  // 鎖對象  
    final Condition notFull = lock.newCondition();  // 寫線程條件 
    final Condition notEmpty = lock.newCondition();  // 讀線程條件
    
    final Integer[] items = new Integer[10]; // 緩存隊列  
    int putptr;  // 寫索引
    int takeptr; // 讀索引
    int count;   // 隊列中存在的數據個數
    
    public void put(Integer x) throws InterruptedException {
        lock.lock();
        try {
            while(count == items.length) {  // 若是隊列滿了  
                notFull.await();  // 阻塞寫線程
            }
            items[putptr] = x;  // 賦值 
            System.out.println("寫入:" + x);
            if(++putptr == items.length) { // 若是寫索引寫到隊列的最後一個位置了,那麼置爲0 
                putptr = 0;
            }
            ++count; // 個數++  
            notEmpty.signal(); // 喚醒讀線程  
        } finally {
            lock.unlock();
        }
    }
    
    public Integer take() throws InterruptedException {
        lock.lock();
        try {
            while(count == 0) { // 若是隊列爲空  
                notEmpty.await(); // 阻塞讀線程
            }
            Integer x = items[takeptr]; // 取值  
            System.out.println("讀取:" + x);
            if(++takeptr == items.length) { // 若是讀索引讀到隊列的最後一個位置了,那麼置爲0  
                takeptr = 0;
            }
            --count; // 個數--  
            notFull.signal();
            return x;
        } finally {
            lock.unlock();
        }
    }
} 

輸出:

.......

相關文章
相關標籤/搜索