線程的【生命週期】和【線程的同步】(多窗口售票例子)

 

 JDK 中用Thread.State 類定義了線程的幾種狀態
要想實現多線程,必須在主線程中建立新的線程對象。Java語言使用Thread類
及其子類的對象來表示線程,在它的一個完整的生命週期中一般要經歷以下的 五
種狀態:安全


新建: 當一個Thread類或其子類的對象被聲明並建立時,新生的線程對象處於新建
狀態多線程


就緒:處於新建狀態的線程被start()後,將進入線程隊列等待CPU時間片,此時它已
具有了運行的條件,只是沒分配到CPU資源ide


運行:當就緒的線程被調度並得到CPU資源時,便進入運行狀態, run()方法定義了線
程的操做和功能this


阻塞:在某種特殊狀況下,被人爲掛起或執行輸入輸出操做時,讓出 CPU 並臨時中
止本身的執行,進入阻塞狀態spa


死亡:線程完成了它的所有工做或線程被提早強制性地停止或出現異常致使結束線程

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

解決方法:code

/**
* 例子:建立三個窗口賣票,總票數爲100張.使用實現Runnable接口的方式
*
* 1.問題:賣票過程當中,出現了重票、錯票 -->出現了線程的安全問題
* 2.問題出現的緣由:當某個線程操做車票的過程當中,還沒有操做完成時,其餘線程參與進來,也操做車票。
* 3.如何解決:當一個線程a在操做ticket的時候,其餘線程不能參與進來。直到線程a操做完ticket時,其餘
* 線程才能夠開始操做ticket。這種狀況即便線程a出現了阻塞,也不能被改變。
*
*
* 4.在Java中,咱們經過同步機制,來解決線程的安全問題。
*
* 方式一:同步代碼塊
*
* synchronized(同步監視器){
* //須要被同步的代碼
*
* }
* 說明:1.操做共享數據的代碼,即爲須要被同步的代碼。 -->不能包含代碼多了,也不能包含代碼少了。
* 2.共享數據:多個線程共同操做的變量。好比:ticket就是共享數據。
* 3.同步監視器,俗稱:鎖。任何一個類的對象,均可以充當鎖。
* 要求:多個線程必需要共用同一把鎖。
*
* 補充:在實現Runnable接口建立多線程的方式中,咱們能夠考慮使用this充當同步監視器。
* 方式二:同步方法。
* 若是操做共享數據的代碼完整的聲明在一個方法中,咱們不妨將此方法聲明同步的。
*
*
* 5.同步的方式,解決了線程的安全問題。---好處
* 操做同步代碼時,只能有一個線程參與,其餘線程等待。至關因而一個單線程的過程,效率低。 ---侷限性
*
* @author ch
* @create 2019-02-13 下午 4:47
*/
class Window1 implements Runnable{

    private int ticket = 100;
//    Object obj = new Object();
//    Dog dog = new Dog();
    @Override
    public void run() {
//        Object obj = new Object();
        while(true){
            synchronized (this){//此時的this:惟一的Window1的對象   //方式二:synchronized (dog) {

                if (ticket > 0) {

                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    System.out.println(Thread.currentThread().getName() + ":賣票,票號爲:" + ticket);


                    ticket--;
                } else {
                    break;
                }
            }
        }
    }
}


public class WindowTest1 {
    public static void main(String[] args) {
        Window1 w = new Window1();

        Thread t1 = new Thread(w);
        Thread t2 = new Thread(w);
        Thread t3 = new Thread(w);

        t1.setName("窗口1");
        t2.setName("窗口2");
        t3.setName("窗口3");

        t1.start();
        t2.start();
        t3.start();
    }

}
相關文章
相關標籤/搜索