Java用同步代碼塊實作線程同步:
本文示例賣票的,三張票,四個視窗出售
testsale1為四個線程處理同一個對象,sale1内有兩個方法,可供run方法調用,一個是未使用同步代碼塊的方法,一個是使用同步代碼塊的方法
testsale2為四個線程處理四個對象,對象不同,但可以同步,直接将同步代碼塊寫入run方法
Thread.start()和Thread.run()的差別:
start是進入就緒不一定去執行,該線程執行時會自動調用内部的run方法。
調用run的話會直接執行。自動将目前線程變為主線程,并沒有實作分線程。
這一點差別可以使用Thread.currentThread().getName()進行驗證
廢話不多說,關于賣票多線程實作方法和具體解釋看代碼
如果看不出來,連續多運作幾次就能看出差別
注釋表示可選的驗證
package ticket;
public class ticket {
public static void main(String[] args) {
testsale1();
testsale2();
}
/**
* 測試sale1的方法 多個線程處理同一對象 實作線程同步
*/
public static void testsale1() {
sale1 s = new sale1();
Thread t1 = new Thread(s, "windows 1");
Thread t2 = new Thread(s, "windows 2");
Thread t3 = new Thread(s, "windows 3");
Thread t4 = new Thread(s, "windows 4");
t1.start();
t2.start();
t3.start();
t4.start();
}
/**
* 測試sale2的方法 多個線程處理不同對象 實作線程同步
*/
public static void testsale2() {
sale2 s1 = new sale2();
sale2 s2 = new sale2();
sale2 s3 = new sale2();
sale2 s4 = new sale2();
Thread t1 = new Thread(s1, "windows 1");
Thread t2 = new Thread(s2, "windows 2");
Thread t3 = new Thread(s3, "windows 3");
Thread t4 = new Thread(s4, "windows 4");
t1.start();
t2.start();
t3.start();
t4.start();
}
}
/**
* 一個類可以包含多個類,至少一個是public 下面類實作的是 使用同步代碼塊的多線程和沒有使用同步代碼塊的多線程差別
* 使用的可以確定進入該代碼塊的隻有一個線程 沒有使用的不能保證進入該代碼快的是一個線程
*
* @author Administrator
*
*/
class sale1 implements Runnable {
static int remainticket = 3;
@Override
public void run() {
// TODO Auto-generated method stub
// saleTicket();
sysale();
}
/**
* 沒使用同步代碼快标記的方法 該方法,可導緻線程不穩定,輸出結果不一緻
*/
private void saleTicket() {
// TODO Auto-generated method stub
if (remainticket > 0) {
remainticket--;
System.out.println(Thread.currentThread().getName() + " " + remainticket);
// remainticket--;
} else {
System.out.println(Thread.currentThread().getName() + " " + "no ticket");
}
}
/**
* 使用同步代碼塊控制的方法 可以保證線程執行時隻有一個線程調用該方法
*/
public synchronized void sysale() {
if (remainticket > 0) {
remainticket--;
System.out.println(Thread.currentThread().getName() + " " + remainticket);
// remainticket--;
} else {
System.out.println(Thread.currentThread().getName() + " " + "no ticket");
}
}
}
/**
* 一個類可以包含多個類,至少一個是public 下面類實作的是 重寫run方法在方法内實作同步代碼塊
*
* @author Administrator
*
*/
class sale2 implements Runnable {
static int remainticket = 3;
/**
* 将同步代碼塊直接寫入run方法 synchronized (實作同步代碼塊的類名.class)
*/
@Override
public void run() {
// TODO Auto-generated method stub
synchronized (sale2.class) {
if (remainticket > 0) {
remainticket--;
System.out.println(Thread.currentThread().getName() + " " + remainticket);
// remainticket--;
} else {
System.out.println(Thread.currentThread().getName() + " " + "no ticket");
}
}
}
}