1. 程式人生 > >Synchronized同步程式碼塊時加鎖物件發生改變會引發什麼執行緒問題

Synchronized同步程式碼塊時加鎖物件發生改變會引發什麼執行緒問題

package com.Synchronized;

public class SynchronizedTest {
	public static void main(String[] args) {
		Test2 t = new Test2();
		//Test3 t = new Test3();
		new Thread(new Runnable() {
			@Override
			public void run() {
				// TODO Auto-generated method stub
				t.A();
			}

		}).start();
		new Thread(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				t.A();
			}

		}).start();
	}
}

class Test2 {
	private Integer i = 41;

	public void A() {
		synchronized (i) {
			System.out.println(i);
			i = 45;
			try {
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

	}
}

class Test3 {
	private Student s = new Student();

	public void A() {
		synchronized (s) {
			System.out.println(s);
			s.name = "李青";
			try {
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

class Student {
	public String name = "亞索";

	@Override
	public String toString() {
		return "Student [name=" + name + "]";
	}
}

41,45同時列印


李青是延遲三秒後列印的

總結:可以看出當synchronized()中被加鎖的物件如果是基本型別的包裝型別或者是String型別,在一個執行緒獲得該物件的鎖之後線上程體裡面如果改變了其引用物件,那麼他所持有的 鎖會立即被釋放,此時極有可能會造成安全問題,如果是一些其它型別,當我們改變它們的屬性(成員變數)時,鎖並不會被釋放。