多線程實現方式?如何啟動多線程?什么情況下會發生線程安全問題?如何解決線程安全問題?


一、實現多線程的幾種方式

1、繼承Threa類

代碼案例如下

任務1

package com.xc.threadDemo;

public class Task1 extends Thread{
    @Override
    public void run() {
        for(int i = 1; i < 10; i++) {
            System.out.println("i===================================" + i);
        }
    }
}

任務2

package com.xc.threadDemo;

public class Task2 extends Thread{
    @Override
    public void run() {
        for(int j = 1; j < 10; j++) {
            System.out.println("j=" + j);
        }
    }
}

線程執行類

package com.xc.threadDemo;

public class Test {
    public static void main(String[] args) {
        Task1 task1 = new Task1();
        Task2 task2 = new Task2();
        //如果調用run方法,程序就會從上至下執行
        task1.run();
        task2.run();
        //只有調用start方法,啟動而不是運行線程,兩個線程才會同時執行
        task1.start();
        task2.start();
    }
}

 

2、實現Runnable接口

代碼案例如下

任務1

package com.xc.threadDemo2;

public class Task1 implements Runnable{

    @Override
    public void run() {
        for(int i = 1; i < 1000; i++) {
            System.out.println("i===================================" + i);
        }
    }
}

 

任務2

package com.xc.threadDemo2;

public class Task2 implements Runnable{

    @Override
    public void run() {
        for(int j = 1; j < 1000; j++) {
            System.out.println("j=" + j);
        }
    }
}

 

線程執行類

package com.xc.threadDemo2;

public class Test {
    public static void main(String[] args) {
        Runnable task1 = new Task1();
        Runnable task2 = new Task2();
        Thread thread1 = new Thread(task1);
        Thread thread2 = new Thread(task2);
        thread1.start();
        thread2.start();
    }
}

 

二、如何啟動線程

如上面的案例所示

1、如果是繼承Thread類,啟動線程使用對象調用start方法即可

2、如果是實現Runnable接口,啟動線程的方式相對復雜一點,但是這是實際開發中使用最多的方式,因為Java是單繼承,一旦繼承了Thread類,就無法繼承其他類

 

三、什么情況下會發生線程安全問題

當多個線程訪問同一個共享數據時,有可能會出現線程安全問題

例如如下案例(火車票購票系統)

 

 

package com.xc.threadDemo3;

public class TicketSystem extends Thread{
    //售票系統只有200張票
    public static int ticketNum = 200;
    
    @Override
    public void run() {
        try {
            //模擬一個售票窗口有1000人排隊買票
            for(int i = 1; i <= 1000; i++) {
                if(ticketNum > 0) {
                    ticketNum--;
                    System.out.println("售票窗口:"+Thread.currentThread()+"通知:恭喜您,成功搶到票,還剩下"+ticketNum+"張票");
                }
                //模擬每個人買票之后與下一個人買票之前的時間間隔
                Thread.sleep(500);
            }
        }catch(Exception e) {
            System.out.println("搶票失敗,請檢查您的網絡!");
        }
    }

}

 

package com.xc.threadDemo3;

public class Test {
    public static void main(String[] args) {
        //模擬同時有三個售票窗口,分別有1000人同時在排隊買票
        TicketSystem ticketSystem1 = new TicketSystem();
        TicketSystem ticketSystem2 = new TicketSystem();
        TicketSystem ticketSystem3 = new TicketSystem();
        ticketSystem1.start();
        ticketSystem2.start();
        ticketSystem3.start();
    }
}

 

 執行結果

售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下8張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下8張票
售票窗口:Thread[Thread-0,5,main]通知:恭喜您,成功搶到票,還剩下7張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下5張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下5張票
售票窗口:Thread[Thread-0,5,main]通知:恭喜您,成功搶到票,還剩下4張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下3張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下3張票
售票窗口:Thread[Thread-0,5,main]通知:恭喜您,成功搶到票,還剩下2張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下0張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下0張票

 

結論:

可以看到同一張票,被賣出去兩次,這是不允許出現的情況

 

四、如何解決線程安全問題

 

解決方案就是加鎖,在關鍵的地方加鎖,就可以解決這樣的問題,代碼如下

 

package com.xc.threadDemo3;

public class TicketSystem extends Thread{
    //售票系統只有200張票
    public static int ticketNum = 200;
    
    @Override
    public void run() {
        try {
            //模擬一個售票窗口有1000人排隊買票
            for(int i = 1; i <= 1000; i++) {
                synchronized (TicketSystem.class) {
                    if(ticketNum > 0) {
                        ticketNum--;
                        System.out.println("售票窗口:"+Thread.currentThread()+"通知:恭喜您,成功搶到票,還剩下"+ticketNum+"張票");
                    }
                    //模擬每個人買票之后與下一個人買票之前的時間間隔
                    Thread.sleep(500);
                }
            }
        }catch(Exception e) {
            System.out.println("搶票失敗,請檢查您的網絡!");
        }
    }

}

 

執行結果

售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下199張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下198張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下197張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下196張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下195張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下194張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下193張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下192張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下191張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下190張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下189張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下188張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下187張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下186張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下185張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下184張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下183張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下182張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下181張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下180張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下179張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下178張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下177張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下176張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下175張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下174張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下173張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下172張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下171張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下170張票
售票窗口:Thread[Thread-0,5,main]通知:恭喜您,成功搶到票,還剩下169張票
售票窗口:Thread[Thread-0,5,main]通知:恭喜您,成功搶到票,還剩下168張票
售票窗口:Thread[Thread-0,5,main]通知:恭喜您,成功搶到票,還剩下167張票
售票窗口:Thread[Thread-0,5,main]通知:恭喜您,成功搶到票,還剩下166張票
售票窗口:Thread[Thread-0,5,main]通知:恭喜您,成功搶到票,還剩下165張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下164張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下163張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下162張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下161張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下160張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下159張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下158張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下157張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下156張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下155張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下154張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下153張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下152張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下151張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下150張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下149張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下148張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下147張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下146張票
售票窗口:Thread[Thread-0,5,main]通知:恭喜您,成功搶到票,還剩下145張票
售票窗口:Thread[Thread-0,5,main]通知:恭喜您,成功搶到票,還剩下144張票
售票窗口:Thread[Thread-0,5,main]通知:恭喜您,成功搶到票,還剩下143張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下142張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下141張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下140張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下139張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下138張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下137張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下136張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下135張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下134張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下133張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下132張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下131張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下130張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下129張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下128張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下127張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下126張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下125張票
售票窗口:Thread[Thread-0,5,main]通知:恭喜您,成功搶到票,還剩下124張票
售票窗口:Thread[Thread-0,5,main]通知:恭喜您,成功搶到票,還剩下123張票
售票窗口:Thread[Thread-0,5,main]通知:恭喜您,成功搶到票,還剩下122張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下121張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下120張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下119張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下118張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下117張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下116張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下115張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下114張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下113張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下112張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下111張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下110張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下109張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下108張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下107張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下106張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下105張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下104張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下103張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下102張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下101張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下100張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下99張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下98張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下97張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下96張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下95張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下94張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下93張票
售票窗口:Thread[Thread-0,5,main]通知:恭喜您,成功搶到票,還剩下92張票
售票窗口:Thread[Thread-0,5,main]通知:恭喜您,成功搶到票,還剩下91張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下90張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下89張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下88張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下87張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下86張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下85張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下84張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下83張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下82張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下81張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下80張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下79張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下78張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下77張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下76張票
售票窗口:Thread[Thread-0,5,main]通知:恭喜您,成功搶到票,還剩下75張票
售票窗口:Thread[Thread-0,5,main]通知:恭喜您,成功搶到票,還剩下74張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下73張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下72張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下71張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下70張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下69張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下68張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下67張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下66張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下65張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下64張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下63張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下62張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下61張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下60張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下59張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下58張票
售票窗口:Thread[Thread-0,5,main]通知:恭喜您,成功搶到票,還剩下57張票
售票窗口:Thread[Thread-0,5,main]通知:恭喜您,成功搶到票,還剩下56張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下55張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下54張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下53張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下52張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下51張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下50張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下49張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下48張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下47張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下46張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下45張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下44張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下43張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下42張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下41張票
售票窗口:Thread[Thread-0,5,main]通知:恭喜您,成功搶到票,還剩下40張票
售票窗口:Thread[Thread-0,5,main]通知:恭喜您,成功搶到票,還剩下39張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下38張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下37張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下36張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下35張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下34張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下33張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下32張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下31張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下30張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下29張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下28張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下27張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下26張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下25張票
售票窗口:Thread[Thread-0,5,main]通知:恭喜您,成功搶到票,還剩下24張票
售票窗口:Thread[Thread-0,5,main]通知:恭喜您,成功搶到票,還剩下23張票
售票窗口:Thread[Thread-0,5,main]通知:恭喜您,成功搶到票,還剩下22張票
售票窗口:Thread[Thread-0,5,main]通知:恭喜您,成功搶到票,還剩下21張票
售票窗口:Thread[Thread-0,5,main]通知:恭喜您,成功搶到票,還剩下20張票
售票窗口:Thread[Thread-0,5,main]通知:恭喜您,成功搶到票,還剩下19張票
售票窗口:Thread[Thread-0,5,main]通知:恭喜您,成功搶到票,還剩下18張票
售票窗口:Thread[Thread-0,5,main]通知:恭喜您,成功搶到票,還剩下17張票
售票窗口:Thread[Thread-0,5,main]通知:恭喜您,成功搶到票,還剩下16張票
售票窗口:Thread[Thread-0,5,main]通知:恭喜您,成功搶到票,還剩下15張票
售票窗口:Thread[Thread-0,5,main]通知:恭喜您,成功搶到票,還剩下14張票
售票窗口:Thread[Thread-0,5,main]通知:恭喜您,成功搶到票,還剩下13張票
售票窗口:Thread[Thread-0,5,main]通知:恭喜您,成功搶到票,還剩下12張票
售票窗口:Thread[Thread-0,5,main]通知:恭喜您,成功搶到票,還剩下11張票
售票窗口:Thread[Thread-0,5,main]通知:恭喜您,成功搶到票,還剩下10張票
售票窗口:Thread[Thread-0,5,main]通知:恭喜您,成功搶到票,還剩下9張票
售票窗口:Thread[Thread-0,5,main]通知:恭喜您,成功搶到票,還剩下8張票
售票窗口:Thread[Thread-0,5,main]通知:恭喜您,成功搶到票,還剩下7張票
售票窗口:Thread[Thread-0,5,main]通知:恭喜您,成功搶到票,還剩下6張票
售票窗口:Thread[Thread-0,5,main]通知:恭喜您,成功搶到票,還剩下5張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下4張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下3張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下2張票
售票窗口:Thread[Thread-2,5,main]通知:恭喜您,成功搶到票,還剩下1張票
售票窗口:Thread[Thread-1,5,main]通知:恭喜您,成功搶到票,還剩下0張票

總結

1、為什么同步代碼塊包裹的部分是 

if(ticketNum > 0) {
                        ticketNum--;
                        System.out.println("售票窗口:"+Thread.currentThread()+"通知:恭喜您,成功搶到票,還剩下"+ticketNum+"張票");
                    }
                    //模擬每個人買票之后與下一個人買票之前的時間間隔
                    Thread.sleep(500);

其他部分為什么不包裹?

 

因為沒有必要包裹,排隊的時候,並不會對共享數據產生影響,隨意插隊並不會對售票系統的票造成什么干擾,只有多個窗口同時操作一張票的時候,才會產生票數錯亂的問題

 

所以同步代碼塊包裹的地方,才是關鍵點所在

 

打一個形象的比喻:

如果很多人排隊小便,所有排隊的人,在關鍵的時候,也就是小便的時候,才需要鎖住,也就是其他人不能共享便池,其他不能進來,但是脫褲子和穿褲子的時候,就沒偶遇必要占用坑位了,這個時候可以到旁邊去進行,所以穿褲子不用加鎖

 

2、為什么會產生數據安全問題,也即是票數錯亂的問題?

 

比如售票系統只剩下最后一張票,窗口1有人在買這張票,然后進入判斷你條件:if(ticketNum > 0),發現滿足條件,但是當票數還沒有執行ticketNum--;操作時,第二個人就開始在窗口2買票,此時他會發現還剩余一張,所以就進行了買票,但實際上第一個人已經買走了,只是票數沒有減少而已,這樣就會發生數據錯亂

 

補充

什么場景下會用到多線程

1、例如我們一開始學習過的《坦克大戰》《飛機大戰》等Java游戲程序,我方飛機、敵機、子彈、背景就分別是一個線程,分別對應一個Java類,所以開發這種游戲一定要使用多線程

2、不管是單核處理器,還是多核處理器,都是可以實現多線程,如果是單核處理器,當你執行多個線程時,就會出現卡頓,程序沒有響應

3、操作系統指控cpu(硬件)來完成任務執行,使用時間調度器,但是時間無法均勻分配,調度cpu進行多線程執行,一會執行以下任務1,然后執行以下任務2

 

疑問

Java是站在了巨人的肩膀上,那么多線程底層的代碼邏輯是如何實現的?


免責聲明!

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



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