關於java多線程

關於同步與互斥

線程是進程的最小單元,同一進程中有多個線程
線程的交互有:互斥與同步

同步:因爲線程之間的合作,如有線程A將計算結果提供給線程B作進一步處理,那麼線程B在線程A將數據送達之前都將處於阻塞狀態。

互斥:系統中的多個線程必然要共享某種系統資源,如共享CPU,共享I/O設備,所謂間接相互制約即源於這種資源共享,打印機就是最好的例子,線程A在使用打印機時,其它線程都要等待,這就是互斥

線程A和線程B互斥訪問某個資源則它們之間就會產個順序問題——要麼線程A等待線程B操作完畢,要麼線程B等待線程操作完畢,這其實就是線程的同步了

同步包括互斥,互斥是一種特殊的同步


線程的方法

這裏寫圖片描述
互斥的實現:synckronized(lockObj–創建的鎖對象)
lockObj.wait()方法是讓線程等待,後面需要用lockObj.notify()或者lockObj.notyfyAll()方法使線程喚醒,這兩個通常是成對出現的

如何理解同步 Wait Set(即線程等待區)

當一個線程獲得資源的時候,會有鎖,當線程獲得的資源不夠的時候,會調用wait()方法,釋放獲得的對象鎖,並進入Wait Set區,讓出資源來讓後續的線程獲取資源來做事,同第一個線程一樣,後續的線程也有可能會wait(),也跟着進入了Wait Set區,當後續的線程執行的差不多了,結束了,要調用notify()去喚醒之前在Wait Set裏的線程,或者notifyAll()喚醒所有線程重新搶佔資源

演示代碼如下:

這裏寫圖片描述


線程同步經典問題重現:生產者與消費者模型

當生產者生產一個資源後,消費者消費一個資源,如果沒有資源,消費者等待生產者生產資源

//生產者和消費者模型
//設置公共資源
class PublicResource{
    private int number=0;
    //增加公共資源
    //synchronize是關鍵字,同static用法,用在方法的前面,表示同步
    public synchronized void increase(){
        while(number!=0){
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        number++;
        System.out.println("生產1個資源,總資源爲:"+number);
        notify();
    }
    //減少公共資源
    public synchronized void decrease(){
        while(number==0){
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
            number--;
            System.out.println("消耗1個資源,總資源爲:"+number);
            notify();
    }
}
//創建生產者線程,負責生產資源
class ProducerThread implements Runnable{
    private PublicResource resource;
    public ProducerThread(PublicResource resource) {  
        this.resource = resource;  
    }  
    @Override
    public void run() {
        for(int i=0;i<10;i++){
            try {
                //睡眠0~1秒的時間
                Thread.sleep((long)(Math.random()*1000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        resource.increase();
    }
}
//創建消費者線程,負責生產資源
class UserThread implements Runnable{
    private PublicResource resource;
    public UserThread(PublicResource resource) {  
        this.resource = resource;  
    }
    @Override
    public void run() {
        for(int i=0;i<10;i++){
            try {
                //睡眠0~1秒的時間
                Thread.sleep((long)(Math.random()*1000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        resource.decrease();;
    }
}


//創建消費者

public class ProduceAndUse {

    public static void main(String[] args) {
        PublicResource resource = new PublicResource();  
        new Thread(new UserThread(resource)).start();  
        new Thread(new UserThread(resource)).start();  
        new Thread(new UserThread(resource)).start(); 
        new Thread(new ProducerThread(resource)).start();  
        new Thread(new ProducerThread(resource)).start();  
        new Thread(new ProducerThread(resource)).start();  
    }

}

結果爲:
這裏寫圖片描述

發佈了25 篇原創文章 · 獲贊 12 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章