天天看點

Java用同步代碼塊實作線程同步Java用同步代碼塊實作線程同步:

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");
			}
		}
	}

}