synchronized同步方法
生活随笔
收集整理的這篇文章主要介紹了
synchronized同步方法
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
『線程安全』與『非線程安全』是學習多線程技術時一定會遇到的經典問題。『非線程安全』其實當多個線程訪問同一個對象中的成員變量時產生的,產生的后果就是『臟讀』,就是取到的數據其實是被更改過的。而『線程安全』就是以獲取的成員變量的值是經過同步處理的,不會出現臟讀的現象。
局部變量是線程安全的
public class Demo01 {public static void main(String[] args) {Demo01Service service = new Demo01Service();Thread t1 = new Demo01ThreadA(service);t1.start();Thread t2 = new Demo01ThreadB(service);t2.start();} }class Demo01Service{public void add(String username){int num = 0;if ("a".equals(username)){num = 100;System.out.println("a set over");// 等待另外一個線程修改num的值try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}}else {num = 200;System.out.println("b set over");}System.out.println("username=" + username + ", num=" + num);} }class Demo01ThreadA extends Thread{private Demo01Service service;public Demo01ThreadA(Demo01Service service){this.service = service;}@Overridepublic void run() {service.add("a");} } class Demo01ThreadB extends Thread{private Demo01Service service;public Demo01ThreadB(Demo01Service service){this.service = service;}@Overridepublic void run() {service.add("b");} }局部變量不存在非線程安全問題,永遠都是線程安全的。這是由局部變量是私有的特征所造成的。
成員變量不是線程安全
public class Demo02 {public static void main(String[] args) {Demo02Service service = new Demo02Service();Thread t1 = new Demo02ThreadA(service);Thread t2 = new Demo02ThreadB(service);t1.start();t2.start();} }class Demo02Service {private int num;synchronized public void add(String username){if ("a".equals(username)){num = 100;System.out.println("a is set");try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}}else{num = 200;System.out.println("b is set");}System.out.println("username=" + username + ", num=" + num);} }class Demo02ThreadA extends Thread{private Demo02Service service;public Demo02ThreadA(Demo02Service service){this.service = service;}@Overridepublic void run() {service.add("a");} }class Demo02ThreadB extends Thread{private Demo02Service service;public Demo02ThreadB(Demo02Service service){this.service = service;}@Overridepublic void run() {service.add("b");} }如果有兩個線程同時操作業務對象中的成員變量,可能會產生『非線程安全』問題,需要在方法前使用關鍵字synchronized進行修飾。
多個對象使用多個對象鎖
public class Demo03 {public static void main(String[] args) {Demo03Service service1 = new Demo03Service();Demo03Service service2 = new Demo03Service();Thread t1 = new Demo03ThreadA(service1);Thread t2 = new Demo03ThreadB(service2);t1.start();t2.start();} }class Demo03Service {private int num;synchronized public void add(String username){if ("a".equals(username)){num = 100;System.out.println("a is set");try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}}else{num = 200;System.out.println("b is set");}System.out.println("username=" + username + ", num=" + num);} }class Demo03ThreadA extends Thread{private Demo03Service service;public Demo03ThreadA(Demo03Service service){this.service = service;}@Overridepublic void run() {service.add("a");} }class Demo03ThreadB extends Thread{private Demo03Service service;public Demo03ThreadB(Demo03Service service){this.service = service;}@Overridepublic void run() {service.add("b");} }synchronized取得的鎖都是對象鎖,而不是把一段代碼或方法作為鎖,所以那個線程先執行帶synchronized關鍵字修飾的方法,哪個方法就持有該方法所屬對象的鎖,其它線程只能呈等待狀態,前提是多個線程訪問的是同一個對象。如果多個線程訪問多個對象,JVM會創建出多個對象鎖。
?
總結
以上是生活随笔為你收集整理的synchronized同步方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 进程、线程
- 下一篇: Callable接口