Java多線程併發筆記04 改變lock 對象、死鎖、鎖的種類

示例程序1.線程中改變lock 對象

/**
 * 鎖對象改變的問題
 * 變了就沒用了
 * */
public class ChangeLock {
	/**
	 * 鎖對象變了,那麼鎖就沒有用了,但若是鎖對象的屬性變了則是不影響鎖的效用
	 */
	private String lock = "lock";
	
	/**
	 * 加同步鎖的目的就是要保證原子性,即一個線程執行此方法體開始並結束後,另執另外一個開始結束
	 */
	private void methgod() {
		synchronized(lock) {
			System.out.println("當前線程"+Thread.currentThread().getName()+"開始");
			/**
			 * 未加這句話:(保持完整的原子性)
			 * 	當前線程t1開始(等待2000毫秒。。。)
				當前線程t1結束(等待100毫秒。。。)
				當前線程t2開始(等待2000毫秒。。。)
				當前線程t2結束
				
				加了這句話:t1,t2同時開始,等2000同時結束
				當前線程t1開始
				當前線程t2開始
				當前線程t1結束
				當前線程t2結束
			 */
			
			lock = "lock change";
			try {
				Thread.sleep(2000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println("當前線程"+Thread.currentThread().getName()+"結束");
		}
	}
	
	public static void main(String[] args) {
		final ChangeLock cl = new ChangeLock(); 
		Thread t1 = new Thread(new Runnable() {
			@Override
			public void run() {
				cl.methgod();
			}
		},"t1");
		
		Thread t2 = new Thread(new Runnable() {
			@Override
			public void run() {
				cl.methgod();
			}
		},"t2");
		
		
		t1.start();
		try {
			Thread.sleep(50);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		t2.start();
	}
	
}

示例程序2:死鎖

public class DeadLock extends Thread{
	
	private String lock1 = "lock1";
	
	private String lock2 = "lock2";
	
	private String tag;
	
	public String getTag() {
		return tag;
	}

	public void setTag(String tag) {
		this.tag = tag;
	}

	@Override
	public void run() {
		if(tag.equals("a")){
			synchronized (lock1) {
				System.out.println("當前線程"+Thread.currentThread().getName()+"進入lock1執行");
				try {
					Thread.sleep(2000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				synchronized (lock2) {
					System.out.println("當前線程"+Thread.currentThread().getName()+"進入lock2執行");
				}
			}
		}
		if(tag.equals("b")){
			synchronized (lock2) {
				System.out.println("當前線程"+Thread.currentThread().getName()+"進入lock2執行");
				try {
					Thread.sleep(2000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				synchronized (lock1) {
					System.out.println("當前線程"+Thread.currentThread().getName()+"進入lock1執行");
				}
			}
		}
	}

	public static void main(String[] args) {
		DeadLock dl1 = new DeadLock();
		dl1.setTag("a");
		
		dl1.start();
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		DeadLock dl2 = new DeadLock();
		dl2.setTag("b");
		dl2.start();

	}

}

示例程序3 :不改變lock對象,改變lock對象屬性值,不會產生線程安全問題

public class ModifyLock {
	private String name;
	
	private int age;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}
	
	
	public synchronized void changeAttri(String name, int age) {
		System.out.println("當前線程"+Thread.currentThread().getName()+"開始");
		this.setAge(age);
		this.setName(name);
		
		System.out.println("當前線程"+Thread.currentThread().getName()+"修改內容爲:"+ name+":"+age);
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("當前線程"+Thread.currentThread().getName()+"結束");
	}
	
	public static void main(String[] args) {
		final ModifyLock cl = new ModifyLock(); 
		Thread t1 = new Thread(new Runnable() {
			@Override
			public void run() {
				cl.changeAttri("aaa",2);
			}
		},"t1");
		
		Thread t2 = new Thread(new Runnable() {
			@Override
			public void run() {
				cl.changeAttri("bbb",3);
			}
		},"t2");
		
		
		t1.start();
		try {
			Thread.sleep(50);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		t2.start();
	}
	
	
}

 示例程序4:鎖的種類

public class ObjectLock {
	public void method1(){
		synchronized (this) {//對象鎖
			try {
				System.out.println("method1......");
				Thread.sleep(2000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
	public void method2(){
		synchronized (ObjectLock.class) {//類鎖
			try {
				System.out.println("method2......");
				Thread.sleep(2000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
	private Object lock = new Object();
	public void method3(){
		synchronized (lock) {//任何對象鎖
			try {
				System.out.println("method3......");
				Thread.sleep(2000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
	
	public static void main(String[] args) {
		final ObjectLock ol = new ObjectLock();
		Thread t1 = new Thread(new Runnable() {
			@Override
			public void run() {
				ol.method1();
			}
		},"t1");
		
		Thread t2 = new Thread(new Runnable() {
			@Override
			public void run() {
				ol.method2();
			}
		},"t2");
		
		Thread t3 = new Thread(new Runnable() {
			@Override
			public void run() {
				ol.method3();
			}
		},"t3");
		
		
		t1.start();
		t2.start();
		t3.start();
	}
}

示例程序5:String對象鎖

public class StringLock {
	public void method() {
		//如果鎖是非new出來的,那麼就是一個常量,則被獨佔while(true)死循環,,若是被new出來的,則2個對象
		/**
		 * 當前線程t2開始
			當前線程t1開始
			當前線程t1結束
			當前線程t2結束
		 */
//		synchronized (new String("字符串常量")) {
			
		/**
		 * 當前線程t1開始
			當前線程t1結束
			當前線程t1開始
			當前線程t1結束
		 */
		synchronized ("字符串常量") {
			try {
				while(true) {
					System.out.println("當前線程"+Thread.currentThread().getName()+"開始");
						Thread.sleep(2000);
					System.out.println("當前線程"+Thread.currentThread().getName()+"結束");
				}
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
	public static void main(String[] args) {
		final StringLock ol = new StringLock();
		Thread t1 = new Thread(new Runnable() {
			@Override
			public void run() {
				ol.method();
			}
		},"t1");
		
		Thread t2 = new Thread(new Runnable() {
			@Override
			public void run() {
				ol.method();
			}
		},"t2");
		
		t1.start();
		t2.start();
	}
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章