02_線程基礎(二)

示例002

package com.bjsxt.base.sync002;
/**
 * 關鍵字synchronized取得的鎖都是對象鎖,而不是把一段代碼(方法)當作鎖,
 * 因此代碼中哪一個線程先執行synchronized關鍵字的方法,哪一個線程就持有該方法所屬對象的鎖(Lock),
 * 
 * 在靜態方法上加synchronized關鍵字,表示鎖定.class類,類一級別的鎖(獨佔.class類)。
 * @author alienware
 *
 */
public class MultiThread {
    //Cannot make a static reference to the non-static field num
	//private int num = 0;
	
	/** static */
	public static synchronized void printNum(String tag){
		try {
			int num = 0;
			if(tag.equals("a")){
				num = 100;
				System.out.println("tag a, set num over!");
				Thread.sleep(1000);
			} else {
				num = 200;
				System.out.println("tag b, set num over!");
			}
			
			System.out.println("tag " + tag + ", num = " + num);
			
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
	//注意觀察run方法輸出順序
	public static void main(String[] args) {
		
		//倆個不一樣的對象
		final MultiThread m1 = new MultiThread();
		final MultiThread m2 = new MultiThread();
		
		Thread t1 = new Thread(new Runnable() {
			@Override
			public void run() {
				m1.printNum("a");
			}
		});
		
		Thread t2 = new Thread(new Runnable() {
			@Override 
			public void run() {
				m2.printNum("b");
			}
		});		
		
		t1.start();
		t2.start();
		
	}
	
	
	
	
}

不帶synchronized的輸出

tag a, set num over!
tag b, set num over!
tag b, num = 200
tag a, num = 100

帶synchronized的輸出

tag a, set num over!
tag a, num = 100
tag b, set num over!
tag b, num = 200

示例003

package com.bjsxt.base.sync003;

/**
 * 對象鎖的同步和異步問題
 * @author alienware
 *
 */
public class MyObject {

	public synchronized void method1(){
		try {
			System.out.println(Thread.currentThread().getName());
			Thread.sleep(4000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
	/** synchronized */
	public  void method2(){
			System.out.println(Thread.currentThread().getName());
	}
	
	public static void main(String[] args) {
		
		final MyObject mo = new MyObject();
		
		/**
		 * 分析:
		 * t1線程先持有object對象的Lock鎖,t2線程能夠以異步的方式調用對象中的非synchronized修飾的方法,而無需等待
		 * t1線程先持有object對象的Lock鎖,t2線程若是在這個時候調用對象中的同步(synchronized)方法則需等待,也就是同步
		 */
		Thread t1 = new Thread(new Runnable() {
			@Override
			public void run() {
				mo.method1();
			}
		},"t1");
		
		Thread t2 = new Thread(new Runnable() {
			@Override
			public void run() {
				mo.method2();
			}
		},"t2");
		
		t1.start();
		t2.start();
		
	}
	
}
相關文章
相關標籤/搜索