一、實現多線程的幾種方式
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是站在了巨人的肩膀上,那么多線程底層的代碼邏輯是如何實現的?