国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

線程的同步和安全

2019-11-14 21:53:24
字體:
來源:轉載
供稿:網友
線程的同步和安全

如果多個線程同時運行同一個線程體,每次運行的結果可能都不一樣

class MyThread implements Runnable{int i = 10;public void run(){while(true){//獲取當前運行線程的名字System.out.PRintln(Thread.currentThread().getName() + i);i--;Thread.yield();if(i < 0){break;}}}}
class Test{public static void main(String args[]){MyThread mt = new MyThread();//生成共用同一線程體的兩個線程對象Thread t1 = new Thread(mt);Thread t2 = new Thread(mt);//設置線程名字t1.setName("A線程:");t2.setName("B線程:");//分別啟動兩個線程t1.start();t2.start();}}

根據上圖我們知道結果明顯有錯誤,這就是多線程運行訪問同一份數據時出現的錯誤。錯誤原因:AB線程輪流運行,假設B線程先運行了幾行代碼后(打印B線程:10)輪到A線程運行。A線程運行線程體后也打印A線程:10

為解決這個問題,我們使用java關鍵字:synchronized

class MyThread implements Runnable{int i = 10;public void run(){while(true){//同步代碼塊synchronized(this){//獲取當前運行線程的名字System.out.println(Thread.currentThread().getName() + i);i--;Thread.yield();if(i < 0){break;}}}}}

使用同步代碼塊后,當A線程執行線程體時,獲得了對象鎖的使用權,即使A線程運行到yield方法時仍持有這個鎖的使用權,B線程沒有得到對象鎖的使用權,則需要等待A線程執行完線程體釋放對象鎖。當B線程獲得了對象鎖的使用權后A線程也需要等待。線程的同步是為了防止多個線程訪問同一數據時,對數據造成的破壞。

同步代碼塊鎖住的到底是什么呢?

class Service{public void fun1(){synchronized(this){try{Thread.sleep(3000);}catch(Exception e){System.out.println(e);}System.out.println("fun1");}}public void fun2(){synchronized(this){System.out.println("fun2");}}}
class MyThread1 implements Runnable{private Service service;public MyThread1(Service service){this.service = service;}public void run(){service.fun1();}}
class MyThread2 implements Runnable{private Service service;public MyThread2(Service service){this.service = service;}public void run(){service.fun2();}}
class Test{public static void main(String args[]){Service service = new Service();Thread t1 = new Thread(new MyThread1(service));Thread t2 = new Thread(new MyThread2(service));t1.start();t2.start();}}

啟動t1線程后,t1線程調用fun1方法,執行同步代碼塊休眠3秒鐘,并持有對象鎖。如果沒有同步代碼塊,t1線程休眠則執行t2線程,但因為fun2方法的同步代碼塊的對象鎖也是this,所以t2線程無法執行,需要等待t1線程釋放對象鎖。由此可見,synchronized鎖住的是對象而不是代碼塊,一旦某一線程獲得了某個對象的對象鎖,那么這個對象的所有同步代碼塊其他線程都不能執行,需要等待對象鎖的釋放。

Synchronized除了用于同步代碼塊,還可用于同步方法,如

public synchronized void fun2(){System.out.println("fun2");}

同步方法和同步代碼塊功能類似,但同步方法鎖住的是this對象,同步代碼塊可以鎖定除了this之外的指定對象。當一個線程調用對象的其中一個同步方法時,那么這個對象的其他同步方法也不能被其他線程使用。  


上一篇:java:eclipse-tomcat 配置

下一篇:Spring AOP

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 瑞安市| 元阳县| 雅安市| 婺源县| 庆安县| 宜阳县| 寿光市| 商城县| 内黄县| 常山县| 高密市| 五大连池市| 山丹县| 普格县| 大石桥市| 安溪县| 东乡| 泌阳县| 徐水县| 临江市| 固阳县| 广水市| 北辰区| 徐闻县| 红河县| 攀枝花市| 盐源县| 江口县| 龙口市| 长葛市| 彩票| 建瓯市| 象山县| 梁河县| 漳浦县| 铜山县| 芜湖市| 昂仁县| 河间市| 邹平县| 广元市|