1. 程式人生 > >java多執行緒2:區域性變數的執行緒安全,實列變數的非執行緒安全

java多執行緒2:區域性變數的執行緒安全,實列變數的非執行緒安全

java多執行緒2:區域性變數的執行緒安全,實列變數的非執行緒安全

“非執行緒安全“就是在多個執行緒訪問同一個物件的例項變數進行併發訪問時候發生,產生的後果就是”髒讀“,也就是取到的資料其實是被修改過的。

a.多執行緒訪問區域性變數是執行緒安全的。

package multiThread.synchro;

public class OneNumber {
	

	public void receiveUserName(String userName) {
		int num = 0;
		if (userName.equals("a")) {
			num = 100;
		} else {
			num = 200;
		}
		System.out.println("userName:" + userName + "     數字是:" + num);
	}
}
package multiThread.synchro;

public class AThread extends Thread {
	private OneNumber oneNumber;

	public AThread(OneNumber oneNumber) {
		this.oneNumber = oneNumber;
	}

	public void run() {
		oneNumber.receiveUserName("a");
	}
}
package multiThread.synchro;

public class BThread extends Thread {
	private OneNumber oneNumber;

	public BThread(OneNumber oneNumber) {
		this.oneNumber = oneNumber;
	}

	public void run() {
		oneNumber.receiveUserName("b");
	}
}
package multiThread.synchro;

public class Main {
	public static void main(String[] args) {
		OneNumber oneNumber = new OneNumber();
		AThread aThread = new AThread(oneNumber);
		BThread bThread = new BThread(oneNumber);
		aThread.start();
		
		bThread.start();
	}
}

控制檯:

 

 

b.如果對上邊OneNumber類稍作修改,將區域性變數num變為例項變數:

package multiThread.synchro;

public class OneNumber {

	int num = 0;

	public void receiveUserName(String userName) {

		if (userName.equals("a")) {
			num = 100;
		} else {
			num = 200;
		}
		System.out.println("userName:" + userName + "     數字是:" + num);
	}
}

控制檯:

c.如何解決併發造成的訪問例項變數的非執行緒安全問題:

加關鍵字:synchronized

package multiThread.synchro;

public class OneNumber {

	int num = 0;

	synchronized public void receiveUserName(String userName) {

		if (userName.equals("a")) {
			num = 100;
		} else {
			num = 200;
		}
		System.out.println("userName:" + userName + "     數字是:" + num);
	}
}

控制檯: