java的多線程啓動後,在沒有使用鎖的狀況下,會各自執行各自的代碼,而無論其它線程運行狀態。這種狀況下,當多個線程使用同一個變量,就會出現數據混亂。(這也就是對線程不安全的理解)java
下面看一個例子: 以銷售火車票爲例,總共有100張火車票,同時開設兩個售票窗口進行售票。編程
對於這個例子,咱們把100張火車票抽象爲一個整形變量--ticket,值爲100。兩個售票窗口抽象爲兩個子線程,在子線程中進行ticket的自減,就是售票行爲。安全
package ticket;
public class Main {
public static void main(String[] args) {
int ticket=100;
Window window1=new Window(ticket);
window1.setName("窗口1");
Window window2=new Window(ticket);
window2.setName("窗口2");
window1.start();
window2.start();
}
}
class Window extends Thread{
private int ticket;
public Window( int ticket) {
this.ticket = ticket;
}
@Override
public void run(){
String windowName=Thread.currentThread().getName();
while(ticket>0){
ticket--;
System.out.println(windowName+"賣出一張票 剩餘票數"+ticket);
}
}
}
複製代碼
運行結果:bash
取部分結果:
窗口2賣出一張票 剩餘票數5
窗口2賣出一張票 剩餘票數4
窗口2賣出一張票 剩餘票數3
窗口2賣出一張票 剩餘票數2
窗口2賣出一張票 剩餘票數1
窗口2賣出一張票 剩餘票數0
窗口1賣出一張票 剩餘票數20
複製代碼
能夠看到,窗口2已經把票賣完了,而窗口1還顯示擁有20張票,這就是由於線程不一樣步,致使線程間共享數據不一致。多線程
package ticket;
public class Main {
public static void main(String[] args) {
Ticket ticket =new Ticket();
ticket.count=100;
Window window1=new Window(ticket);
window1.setName("窗口1");
Window window2=new Window(ticket);
window2.setName("窗口2");
window1.start();
window2.start();
}
}
class Window extends Thread{
private Ticket ticket;
public Window( Ticket ticket) {
this.ticket = ticket;
}
@Override
public void run(){
String windowName=Thread.currentThread().getName();
while(ticket.count>0){
synchronized (ticket) {
ticket.count--;
System.out.println(windowName + "賣出一張票 剩餘票數" + ticket.count);
}
}
}
}
class Ticket {
int count;
}
複製代碼
取部分結果:
窗口1賣出一張票 剩餘票數99
窗口1賣出一張票 剩餘票數98
窗口1賣出一張票 剩餘票數97
窗口1賣出一張票 剩餘票數96
窗口1賣出一張票 剩餘票數95
窗口1賣出一張票 剩餘票數94
窗口1賣出一張票 剩餘票數93
窗口1賣出一張票 剩餘票數92
窗口1賣出一張票 剩餘票數91
窗口1賣出一張票 剩餘票數90
窗口1賣出一張票 剩餘票數89
窗口1賣出一張票 剩餘票數88
窗口1賣出一張票 剩餘票數87
窗口1賣出一張票 剩餘票數86
窗口1賣出一張票 剩餘票數85
窗口1賣出一張票 剩餘票數84
窗口1賣出一張票 剩餘票數83
窗口2賣出一張票 剩餘票數82
窗口2賣出一張票 剩餘票數81
窗口2賣出一張票 剩餘票數80
窗口2賣出一張票 剩餘票數79
窗口2賣出一張票 剩餘票數78
複製代碼
能夠看到,加上線程同步後,窗口1和窗口2實現了票數的共享,票數在逐一的減小。ide
關於線程同步的具體方式,見下一章節。this
ps:該同步代碼有一個問題,你們能夠運行代碼後想一想看問題在哪裏以及怎麼解決(該問題剛好反應在多線程編程中,你以爲是這樣,可實際不是這樣)spa