三個線程a、b、c並發運行,b,c需要a線程的數據怎么實現(semaphore.acquire()方法和permit標記)


public class ThreadCommunication {
    /**
     * 三個線程a、b、c並發運行,b,c需要a線程的數據怎么實現
     *
     * 根據問題的描述,通過三個線程,ThreadA ThreadB ThreadC
     * ThreadA用於初始化數據num,只有num初始化完成之后再讓ThreadB和ThreadC獲取到初始化的變量num。
     *
     *
     * 分析過程如下:
     * 考慮到線程的不確定性,因此我們不能確保ThreadA就一定先於ThreadB和ThreadC前執行,就算
     * ThreadA先執行了,我們也無法保證ThreadA什么時候才能將變量num初始化完成。因此我們必須讓
     * ThreadB和ThreadC去等待ThreadA完成任務后發出的消息
     *
     * 解決兩個問題:
     * 1:讓ThreadB和ThreadC先執行完
     * 2:ThreadA執行完之后給ThreadB和ThreadC發送消息
     */
    /**
     * 兩種解決方案
     * 1、使用純Java API的Semaphore類來控制線程的等待和釋放
     * 2、使用Android提供的消息機制
     */

    //定義一個變量作為數據
    private static int num;

    public static void main(String[] args) {
        Thread threadA = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    //模擬耗時操作之后初始化變量num
                    Thread.sleep(1000);
                    num=1;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        Thread threadB = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"獲取到num的值為:"+num);
            }
        });
        Thread threadC = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"獲取到num的值為:"+num);
            }
        });
        //同時開啟三個線程
        threadA.start();
        threadB.start();
        threadC.start();
    }
}

 運行結果:

Thread-2獲取到num的值為:0
Thread-1獲取到num的值為:0

解決方案1:

  

public class ThreadCommunication {
    /**
     * 三個線程a、b、c並發運行,b,c需要a線程的數據怎么實現
public class ThreadCommunication {

    //定義一個變量作為數據
    private static int num;
    /**
     * 定義一個信號量,該類內部維持了多個線程鎖,可以阻塞多個線程,釋放多個線程
     * 線程的阻塞是和釋放是通過permit概念來實現的
     * 線程通過semaphore.acquire()方法獲取permit,如果當前線程有permit則分配給該線程
     * 如果沒有則阻塞該線程直到semaphore
     * 調用release()方法釋放permit
     * 構造函數中參數:permit(允許)個數;
     */
    private static Semaphore semaphore = new Semaphore(0);

    public static void main(String[] args) {
        Thread threadA = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    //模擬耗時操作之后初始化變量num
                    Thread.sleep(1000);
                    num = 1;
                    //初始化參數后釋放兩個permit
                    semaphore.release(2);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        Thread threadB = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    //獲取permit,如果semaphore沒有可用的permit則等待,如果有則消耗一個
                    semaphore.acquire();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"獲取到的num的值為:"+num);
            }
        });
        Thread threadC = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    //獲取permit,如果semaphore沒有可用的permit則等待,如果有則消耗一個
                    semaphore.acquire();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"獲取到的num的值為:"+num);
            }
        });
        //同時開啟三個線程
        threadA.start();
        threadB.start();
        threadC.start();
    }
}

運行結果:

Thread-1獲取到的num的值為:1
Thread-2獲取到的num的值為:1

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM