亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Java > 正文

java中實現同步的兩種方式:syschronized和lock的區別和聯系

2019-11-11 04:59:09
字體:
來源:轉載
供稿:網友

java中實現同步的兩種方式:syschronized和lock的區別和聯系

   Lock是java.util.concurrent.locks包下的接口,Lock 實現提供了比使用synchronized 方法和語句可獲得的更廣泛的鎖定操作,它能以更優雅的方式處理線程同步問題,我們拿Java線程(二)中的一個例子簡單的實現一下和sychronized一樣的效果,代碼如下:

 

public class LockTest {      public static void main(String[] args) {          final Outputter1 output = new Outputter1();          new Thread() {              public void run() {                  output.output("zhangsan");              };          }.start();                new Thread() {              public void run() {                  output.output("lisi");              };          }.start();      }  }  class Outputter1 {      PRivate Lock lock = new ReentrantLock();// 鎖對象      public void output(String name) {          // TODO 線程輸出方法          lock.lock();// 得到鎖          try {              for(int i = 0; i < name.length(); i++) {                  System.out.print(name.charAt(i));              }          } finally {              lock.unlock();// 釋放鎖          }      }  }  

        這樣就實現了和sychronized一樣的同步效果,需要注意的是,用sychronized修飾的方法或者語句塊在代碼執行完之后鎖自動釋放,而用Lock需要我們手動釋放鎖,所以為了保證鎖最終被釋放(發生異常情況),要把互斥區放在try內,釋放鎖放在finally內。

 

        如果說這就是Lock,那么它不能成為同步問題更完美的處理方式,下面要介紹的是讀寫鎖(ReadWriteLock),我們會有一種需求,在對數據進行讀寫的時候,為了保證數據的一致性和完整性,需要讀和寫是互斥的,寫和寫是互斥的,但是讀和讀是不需要互斥的,這樣讀和讀不互斥性能更高些,來看一下不考慮互斥情況的代碼原型:

 

public class ReadWriteLockTest {      public static void main(String[] args) {          final Data data = new Data();          for (int i = 0; i < 3; i++) {              new Thread(new Runnable() {                  public void run() {                      for (int j = 0; j < 5; j++) {                          data.set(new Random().nextInt(30));                      }                  }              }).start();          }                 for (int i = 0; i < 3; i++) {              new Thread(new Runnable() {                  public void run() {                      for (int j = 0; j < 5; j++) {                          data.get();                      }                  }              }).start();          }      }  }  class Data {          private int data;// 共享數據          public void set(int data) {          System.out.println(Thread.currentThread().getName() + "準備寫入數據");          try {              Thread.sleep(20);          } catch (InterruptedException e) {              e.printStackTrace();          }          this.data = data;          System.out.println(Thread.currentThread().getName() + "寫入" + this.data);      }         public void get() {          System.out.println(Thread.currentThread().getName() + "準備讀取數據");          try {              Thread.sleep(20);          } catch (InterruptedException e) {              e.printStackTrace();          }          System.out.println(Thread.currentThread().getName() + "讀取" + this.data);      }  }  

        部分輸出結果:

 

 

Thread-1準備寫入數據  Thread-3準備讀取數據  Thread-2準備寫入數據  Thread-0準備寫入數據  Thread-4準備讀取數據  Thread-5準備讀取數據  Thread-2寫入12  Thread-4讀取12  Thread-5讀取5  Thread-1寫入12  

        我們要實現寫入和寫入互斥,讀取和寫入互斥,讀取和讀取互斥,在set和get方法加入sychronized修飾符:

 

 

public synchronized void set(int data) {...}      public synchronized void get() {...}  

        部分輸出結果:

Thread-0準備寫入數據  Thread-0寫入9  Thread-5準備讀取數據  Thread-5讀取9  Thread-5準備讀取數據  Thread-5讀取9  Thread-5準備讀取數據  Thread-5讀取9  Thread-5準備讀取數據  Thread-5讀取9  

        我們發現,雖然寫入和寫入互斥了,讀取和寫入也互斥了,但是讀取和讀取之間也互斥了,不能并發執行,效率較低,用讀寫鎖實現代碼如下:

 

 

class Data {          private int data;// 共享數據      private ReadWriteLock rwl = new ReentrantReadWriteLock();         public void set(int data) {          rwl.writeLock().lock();// 取到寫鎖          try {              System.out.println(Thread.currentThread().getName() + "準備寫入數據");              try {                  Thread.sleep(20);              } catch (InterruptedException e) {                  e.printStackTrace();              }              this.data = data;              System.out.println(Thread.currentThread().getName() + "寫入" + this.data);          } finally {              rwl.writeLock().unlock();// 釋放寫鎖          }      }         public void get() {          rwl.readLock().lock();// 取到讀鎖          try {              System.out.println(Thread.currentThread().getName() + "準備讀取數據");              try {                  Thread.sleep(20);              } catch (InterruptedException e) {                  e.printStackTrace();              }              System.out.println(Thread.currentThread().getName() + "讀取" + this.data);          } finally {              rwl.readLock().unlock();// 釋放讀鎖          }      }  }  

 

        部分輸出結果:

 

Thread-4準備讀取數據  Thread-3準備讀取數據  Thread-5準備讀取數據  Thread-5讀取18  Thread-4讀取18  Thread-3讀取18  Thread-2準備寫入數據  Thread-2寫入6  Thread-2準備寫入數據  Thread-2寫入10  Thread-1準備寫入數據  Thread-1寫入22  Thread-5準備讀取數據  

        從結果可以看出實現了我們的需求,這只是鎖的基本用法,鎖的機制還需要繼續深入學習。

        本文來自:高爽|Coder,原文地址:http://blog.csdn.net/ghsau/article/details/7461369,轉載請注明。

 

 

 

 

在java中有兩種方式實現原子性操作(即同步操作):1)使用同步關鍵字synchronized2)使用lock鎖機制其中也包括相應的讀寫鎖

package com.xiaohao.test;

import java.util.Random;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReadWriteLock;import java.util.concurrent.locks.ReentrantLock;import java.util.concurrent.locks.ReentrantReadWriteLock;

public class Test {public static void main(String[] args) {final LockTest lock=new LockTest(); //輸出張三 new Thread(){public void run(){ lock.test("張三張三張三張三張三張三張三張三張三張三");} }.start();//輸出李四new Thread(){public void run(){lock.test("李四李四李四李四李四李四李四李四李四李四");System.out.println ("/n---------------------------------------------------------------");}}.start();//---------------------------------------------------------------//模擬寫入數據的for (int i = 0; i < 3; i++) { new Thread(){ public void run() { for (int j = 0; j < 5; j++) { // lock.set(new Random().nextInt(30)); lock.set2(new Random().nextInt(30));

} } }.start();}//模擬讀取數據的for (int i = 0; i < 3; i++) { new Thread(){ public void run() { for (int j = 0; j < 5; j++) { // lock.get(); lock.get2(); } } }.start();}}}

class LockTest{private Lock lock=new ReentrantLock(); //創建普通的鎖private ReadWriteLock readWriteLock=new ReentrantReadWriteLock();//創建讀寫鎖private int data;// 共享數據 //實現同步的方法一 使用同步關鍵字 synchronizedpublic synchronized void test(String name){//下面的相關操作是一個原子性的操作// lock.lock();// 得到鎖 try { for(int i = 0; i < name.length(); i++) { System.out.print(name.charAt(i)); } } finally { // lock.unlock();// 釋放鎖 } }//實現同步的方法二 使用lock鎖機制public void test2(String name){//下面的相關操作是一個原子性的操作lock.lock();// 得到鎖 try { for(int i = 0; i < name.length(); i++) { System.out.print(name.charAt(i)); } } finally { lock.unlock();// 釋放鎖 } }//使用set方法模擬寫入數據 //使用 synchronized 實現了讀讀,寫寫,讀寫之間的互斥 ,但讀讀之間的互斥是沒有什么必要的public synchronized void set(int data){System.out.println(Thread.currentThread().getName() + "準備寫入數據"); try { Thread.sleep(20); } catch (InterruptedException e) { e.printStackTrace(); } this.data = data; System.out.println(Thread.currentThread().getName() + "寫入" + this.data); }//使用get方法模擬讀取數據//使用 synchronized 實現了讀讀,寫寫,讀寫之間的互斥 ,但讀讀之間的互斥是沒有什么必要的public synchronized void get() { System.out.println(Thread.currentThread().getName() + "準備讀取數據"); try { Thread.sleep(20); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "讀取" + this.data); } //使用set方法模擬寫入數據 //使用 讀寫鎖實現了寫寫,讀寫之間的互斥 ,但讀讀之間的互斥是沒有什么必要的public void set2(int data){readWriteLock.writeLock().lock();//獲取寫入鎖try{System.out.println(Thread.currentThread().getName() + "準備寫入數據"); try { Thread.sleep(20); } catch (InterruptedException e) { e.printStackTrace(); } this.data = data; System.out.println(Thread.currentThread().getName() + "寫入" + this.data); }finally{readWriteLock.writeLock().unlock();}}//使用get方法模擬讀取數據//使用 讀寫鎖實現了寫寫,讀寫之間的互斥 ,但讀讀之間的互斥是沒有什么必要的public void get2() { //獲取相應的讀鎖readWriteLock.readLock().lock();try{ System.out.println(Thread.currentThread().getName() + "準備讀取數據"); try { Thread.sleep(20); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "讀取" + this.data); }finally{// 釋放相應的寫鎖readWriteLock.readLock().unlock();}} }

 

 

 

線程同步經典版:

package com.xiaohao.test;

import java.util.concurrent.locks.ReentrantReadWriteLock;

public class Test2{

 public static void main(String[] args){

  final LockTest2 lockTest=new LockTest2();  

 for(int i=0;i<3;i++)   {    

new Thread(){        

  public void run(){         

        try {  

         for (int j = 0; j < 3; j++) {     

         lockTest.setValue();    

      }    } catch (InterruptedException e) {  

   // TODO Auto-generated catch block     e.printStackTrace();  

  }       

    }      

    }.start();  

 }  

 for(int i=0;i<3;i++)   {  

        new Thread(){     

      public void run(){                

   try {         

  for (int j = 0; j < 3; j++) { 

    lockTest.getValue();       

    }    

} catch (InterruptedException e)

{     // TODO Auto-generated catch block     e.printStackTrace();    }       

    }       

   }.start();  

}    

 }  

}

class  LockTest2 {

 int data=0;  

ReentrantReadWriteLock lock= new ReentrantReadWriteLock();// 鎖對象

   public void setValue() throws InterruptedException{   

lock.writeLock().lock();  

 System.out.println("正在使用寫鎖......");    

data=(int) (Math.random()*10);   

 System.out.println("正在寫入:"+data);   

 Thread.sleep(500);  

 System.out.println("寫鎖調用完畢---------------------------");

  lock.writeLock().unlock();  }  

 public void getValue() throws InterruptedException{

  lock.readLock().lock();     

System.out.println("正在使用讀鎖...........................................");

   System.out.println("正在讀入:"+data);    Thread.sleep(500);

  System.out.println("讀鎖調用完畢......");

  lock.readLock().unlock();  

}

}

 

 **** 當一個線程進入了一個對象是的synchronized方法,那么其它線程還能掉否調用此對象的其它方法?

        這個問題需要分幾種情況進行討論。

      1)查看其它方法是否使用了同步關鍵字(synchronized)修飾,如果沒有的話就可以調用相關的方法。

      2)在當前synchronized方法中是否調用了wait方法,如果調用了,則對應的鎖已經釋放,可以訪問了。

      3)如果其它方法也使用synchronized修飾,并且當前同步方法中沒有調用wait方法的話,這樣是不允許訪問的。

      4)如果其它方法是靜態方法的話,由于靜態方法和對象是扯不上什么關系,對于靜態同步方法而言,其對應的同步監視器為當前類的字節碼

           所以肯定可以訪問的了。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国内精品久久久久影院 日本资源| 91最新国产视频| 日韩欧美在线中文字幕| 国内揄拍国内精品少妇国语| 日韩av影视综合网| 国内伊人久久久久久网站视频| 欧美性高潮在线| 国产精品久久久久久久app| 日韩欧美国产一区二区| 免费99精品国产自在在线| 日韩av123| 日韩在线视频网站| 热久久99这里有精品| 欧美成人全部免费| 欧美精品一区在线播放| 2018日韩中文字幕| 欧美国产精品日韩| 国产精品久久久久久久久| 国产成人精品日本亚洲专区61| 亚洲二区中文字幕| 欧美一区二区三区艳史| 亚洲www在线观看| 最新中文字幕亚洲| 亚洲高清久久久久久| 国产日本欧美一区二区三区在线| 亚洲精品99久久久久| 亚洲国产又黄又爽女人高潮的| 久久久精品日本| 久久久精品影院| 亚洲影院在线看| 亚洲欧洲一区二区三区久久| 久久91亚洲精品中文字幕奶水| 欧美高清视频在线播放| 国产在线a不卡| 国产精品综合久久久| 91精品国产网站| 国产精品成av人在线视午夜片| 精品国产福利在线| 亚洲专区在线视频| 最近2019中文免费高清视频观看www99| 国产亚洲精品va在线观看| 免费91在线视频| 欧美日韩福利在线观看| 91麻豆桃色免费看| 国产精品91一区| 国产精品444| 日韩亚洲精品电影| 亚洲成人av资源网| www高清在线视频日韩欧美| 日本午夜在线亚洲.国产| 国产精品一区二区3区| 欧美精品第一页在线播放| 日韩激情在线视频| 美日韩精品免费观看视频| 日韩av在线资源| 亚洲视频欧洲视频| 国产专区精品视频| 亚洲性无码av在线| 美女福利视频一区| 亚洲自拍小视频免费观看| 一个人看的www久久| 一区二区三区日韩在线| 亚洲另类激情图| 亚洲视频综合网| 国产精品极品美女在线观看免费| 久久久久久免费精品| 久久九九全国免费精品观看| 在线电影中文日韩| 91久久精品国产91久久性色| 9.1国产丝袜在线观看| 亚洲欧美中文日韩在线| 亚洲一区中文字幕在线观看| 国产在线视频不卡| 欧美激情综合色综合啪啪五月| 亚洲欧洲日本专区| 欧美视频13p| 国产精品高精视频免费| 亚洲色图色老头| 亚洲色图偷窥自拍| 国产成人精品综合| 久久久久这里只有精品| 欧美日韩在线免费| 国产精品久久久久久av福利软件| 亚洲综合一区二区不卡| 国产精品无码专区在线观看| 成人女保姆的销魂服务| 亚洲97在线观看| 中文在线资源观看视频网站免费不卡| 最近中文字幕mv在线一区二区三区四区| 亚洲欧美一区二区三区四区| 亚洲一区二区在线播放| 欧美黑人一级爽快片淫片高清| 欧美激情乱人伦| 欧美又大又硬又粗bbbbb| 亚洲一区二区三区777| 91久久在线观看| 一夜七次郎国产精品亚洲| 欧美日韩国产在线播放| 欧美日韩另类字幕中文| 国产精品99久久久久久人| 日韩电影在线观看永久视频免费网站| 国产91精品青草社区| 欧美午夜美女看片| 亚洲欧美国产一区二区三区| 久久成人这里只有精品| 欧美成人全部免费| 97精品伊人久久久大香线蕉| 国产97在线|亚洲| 亚洲国产成人在线播放| 亚洲欧美在线一区| 久久精品成人一区二区三区| 成人激情综合网| 91精品国产自产在线| 91国内精品久久| 久久精品视频在线播放| 日韩欧美在线视频日韩欧美在线视频| 欧美丰满少妇xxxxx做受| 97国产一区二区精品久久呦| 日韩av成人在线| 2019中文字幕在线免费观看| 91免费视频国产| 91国产精品视频在线| 欧美国产日韩在线| 亚洲图片欧美午夜| 久久综合伊人77777蜜臀| 午夜剧场成人观在线视频免费观看| 成人国产精品免费视频| 在线观看免费高清视频97| 亚洲午夜性刺激影院| 91超碰中文字幕久久精品| 日韩在线视频中文字幕| 欧美丰满少妇xxxxx| 日韩欧美国产一区二区| 亚洲国产精品人人爽夜夜爽| 国产精品中文在线| 日韩极品精品视频免费观看| 97超级碰碰人国产在线观看| 欧美激情二区三区| 91产国在线观看动作片喷水| 欧美一级高清免费播放| 亚洲成人久久久久| 日本成人在线视频网址| 国产日韩欧美一二三区| 国产a级全部精品| 911国产网站尤物在线观看| 久久91精品国产91久久跳| 蜜月aⅴ免费一区二区三区| 日韩美女激情视频| 欧美日韩国产一区中文午夜| 欧美午夜久久久| 亚洲一区二区自拍| 欧美性猛交xxxx乱大交3| 精品av在线播放| 久久资源免费视频| 国产手机视频精品| 久久精品国产2020观看福利| 久久影视电视剧免费网站清宫辞电视| 国产日韩av在线播放| 亚洲国产天堂久久综合网| 国产精品女人久久久久久| 欧美午夜女人视频在线| 亚洲国产精品字幕| 日韩精品中文字幕在线| 亚洲一区免费网站|