<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    jinfeng_wang

    G-G-S,D-D-U!

    BlogJava 首頁(yè) 新隨筆 聯(lián)系 聚合 管理
      400 Posts :: 0 Stories :: 296 Comments :: 0 Trackbacks
    http://www.tuicool.com/articles/2aeUBfe

    楔子

    最近一直都比較忙,沒(méi)有時(shí)間寫(xiě)博客了。今天項(xiàng)目終于灰度了,可以有時(shí)間寫(xiě)寫(xiě)博客,看看文章了!!!╮(╯▽╰)╭

    今天要寫(xiě)的主題是Java的基礎(chǔ)知識(shí),Synchronized和Lock鎖的區(qū)別!!!

    區(qū)別

    1、ReentrantLock擁有Synchronized相同的并發(fā)性和內(nèi)存語(yǔ)義,此外還多了 鎖投票,定時(shí)鎖等候和中斷鎖等候等特性。

    線程A和B都要獲取對(duì)象O的鎖定,假設(shè)A獲取了對(duì)象O鎖,B將等待A釋放對(duì)O的鎖定

    如果使用 synchronized ,如果A不釋放,B將一直等下去,不能被中斷

    如果 使用ReentrantLock,如果A不釋放,可以使B在等待了足夠長(zhǎng)的時(shí)間以后,中斷等待,而干別的事情

    ReentrantLock獲取鎖定與三種方式:

    • lock(), 如果獲取了鎖立即返回,如果別的線程持有鎖,當(dāng)前線程則一直處于休眠狀態(tài),直到獲取鎖

    • tryLock(), 如果獲取了鎖立即返回true,如果別的線程正持有鎖,立即返回false;

    • tryLock(long timeout,TimeUnit unit), 如果獲取了鎖定立即返回true,如果別的線程正持有鎖,會(huì)等待參數(shù)給定的時(shí)間,在等待的過(guò)程中,如果獲取了鎖定,就返回true,如果等待超時(shí),返回false;

    • lockInterruptibly:如果獲取了鎖定立即返回,如果沒(méi)有獲取鎖定,當(dāng)前線程處于休眠狀態(tài),直到或者鎖定,或者當(dāng)前線程被別的線程中斷

    2、synchronized是在JVM層面上實(shí)現(xiàn)的,不但可以通過(guò)一些監(jiān)控工具監(jiān)控synchronized的鎖定,而且在代碼執(zhí)行時(shí)出現(xiàn)異常,JVM會(huì)自動(dòng)釋放鎖定,但是使用Lock則不行,lock是通過(guò)代碼實(shí)現(xiàn)的,要保證鎖定一定會(huì)被釋放,就必須將unLock()放到finally{}中

    3、在資源競(jìng)爭(zhēng)不是很激烈的情況下,Synchronized的性能要優(yōu)于ReetrantLock,但是在資源競(jìng)爭(zhēng)很激烈的情況下,Synchronized的性能會(huì)下降幾十倍,但是ReetrantLock的性能能維持常態(tài);

    5.0的多線程任務(wù)包對(duì)于同步的性能方面有了很大的改進(jìn),在原有synchronized關(guān)鍵字的基礎(chǔ)上,又增加了ReentrantLock,以及各種Atomic類。了解其性能的優(yōu)劣程度,有助與我們?cè)谔囟ǖ那樾蜗伦龀稣_的選擇。

    簡(jiǎn)單的總結(jié)

    • synchronized:

      在資源競(jìng)爭(zhēng)不是很激烈的情況下,偶爾會(huì)有同步的情形下,synchronized是很合適的。原因在于,編譯程序通常會(huì)盡可能的進(jìn)行優(yōu)化synchronize,另外可讀性非常好,不管用沒(méi)用過(guò)5.0多線程包的程序員都能理解。

    • ReentrantLock:

      ReentrantLock提供了多樣化的同步,比如有時(shí)間限制的同步,可以被Interrupt的同步(synchronized的同步是不能Interrupt的)等。在資源競(jìng)爭(zhēng)不激烈的情形下,性能稍微比synchronized差點(diǎn)點(diǎn)。但是當(dāng)同步非常激烈的時(shí)候,synchronized的性能一下子能下降好幾十倍。而ReentrantLock確還能維持常態(tài)。

    • Atomic:

      和上面的類似,不激烈情況下,性能比synchronized略遜,而激烈的時(shí)候,也能維持常態(tài)。激烈的時(shí)候,Atomic的性能會(huì)優(yōu)于ReentrantLock一倍左右。但是其有一個(gè)缺點(diǎn),就是只能同步一個(gè)值,一段代碼中只能出現(xiàn)一個(gè)Atomic的變量,多于一個(gè)同步無(wú)效。因?yàn)樗荒茉诙鄠€(gè)Atomic之間同步。

    所以,我們寫(xiě)同步的時(shí)候,優(yōu)先考慮synchronized,如果有特殊需要,再進(jìn)一步優(yōu)化。ReentrantLock和Atomic如果用的不好,不僅不能提高性能,還可能帶來(lái)災(zāi)難。

    測(cè)試結(jié)果

    先貼測(cè)試結(jié)果:再貼代碼(Atomic測(cè)試代碼不準(zhǔn)確,一個(gè)同步中只能有1個(gè)Actomic,這里用了2個(gè),但是這里的測(cè)試只看速度)

    round:100000 thread:5

    Sync = 35301694

    Lock = 56255753

    Atom = 43467535

    round:200000 thread:10

    Sync = 110514604

    Lock = 204235455

    Atom = 170535361

    round:300000 thread:15

    Sync = 253123791

    Lock = 448577123

    Atom = 362797227

    round:400000 thread:20

    Sync = 16562148262

    Lock = 846454786

    Atom = 667947183

    round:500000 thread:25

    Sync = 26932301731

    Lock = 1273354016

    Atom = 982564544

    Java代碼

    package test.thread;       import static java.lang.System.out;       import java.util.Random;      import java.util.concurrent.BrokenBarrierException;      import java.util.concurrent.CyclicBarrier;      import java.util.concurrent.ExecutorService;      import java.util.concurrent.Executors;      import java.util.concurrent.atomic.AtomicInteger;      import java.util.concurrent.atomic.AtomicLong;      import java.util.concurrent.locks.ReentrantLock;       public class TestSyncMethods {           public static void test(int round,int threadNum,CyclicBarrier cyclicBarrier){              new SyncTest("Sync",round,threadNum,cyclicBarrier).testTime();              new LockTest("Lock",round,threadNum,cyclicBarrier).testTime();              new AtomicTest("Atom",round,threadNum,cyclicBarrier).testTime();          }           public static void main(String args[]){               for(int i=0;i<5;i++){                  int round=100000*(i+1);                  int threadNum=5*(i+1);                  CyclicBarrier cb=new CyclicBarrier(threadNum*2+1);                  out.println("==========================");                  out.println("round:"+round+" thread:"+threadNum);                  test(round,threadNum,cb);               }          }      }       class SyncTest extends TestTemplate{          public SyncTest(String _id,int _round,int _threadNum,CyclicBarrier _cb){              super( _id, _round, _threadNum, _cb);          }          @Override         /**         * synchronized關(guān)鍵字不在方法簽名里面,所以不涉及重載問(wèn)題         */         synchronized long  getValue() {              return super.countValue;          }          @Override         synchronized void  sumValue() {              super.countValue+=preInit[index++%round];          }      }        class LockTest extends TestTemplate{          ReentrantLock lock=new ReentrantLock();          public LockTest(String _id,int _round,int _threadNum,CyclicBarrier _cb){              super( _id, _round, _threadNum, _cb);          }          /**         * synchronized關(guān)鍵字不在方法簽名里面,所以不涉及重載問(wèn)題         */         @Override         long getValue() {              try{                  lock.lock();                  return super.countValue;              }finally{                  lock.unlock();              }          }          @Override         void sumValue() {              try{                  lock.lock();                  super.countValue+=preInit[index++%round];              }finally{                  lock.unlock();              }          }      }        class AtomicTest extends TestTemplate{          public AtomicTest(String _id,int _round,int _threadNum,CyclicBarrier _cb){              super( _id, _round, _threadNum, _cb);          }          @Override         /**         * synchronized關(guān)鍵字不在方法簽名里面,所以不涉及重載問(wèn)題         */         long  getValue() {              return super.countValueAtmoic.get();          }          @Override         void  sumValue() {              super.countValueAtmoic.addAndGet(super.preInit[indexAtomic.get()%round]);          }      }      abstract class TestTemplate{          private String id;          protected int round;          private int threadNum;          protected long countValue;          protected AtomicLong countValueAtmoic=new AtomicLong(0);          protected int[] preInit;          protected int index;          protected AtomicInteger indexAtomic=new AtomicInteger(0);          Random r=new Random(47);          //任務(wù)柵欄,同批任務(wù),先到達(dá)wait的任務(wù)掛起,一直等到全部任務(wù)到達(dá)制定的wait地點(diǎn)后,才能全部喚醒,繼續(xù)執(zhí)行          private CyclicBarrier cb;          public TestTemplate(String _id,int _round,int _threadNum,CyclicBarrier _cb){              this.id=_id;              this.round=_round;              this.threadNum=_threadNum;              cb=_cb;              preInit=new int[round];              for(int i=0;i<preInit.length;i++){                  preInit[i]=r.nextInt(100);              }          }           abstract void sumValue();          /*         * 對(duì)long的操作是非原子的,原子操作只針對(duì)32位         * long是64位,底層操作的時(shí)候分2個(gè)32位讀寫(xiě),因此不是線程安全         */         abstract long getValue();           public void testTime(){              ExecutorService se=Executors.newCachedThreadPool();              long start=System.nanoTime();              //同時(shí)開(kāi)啟2*ThreadNum個(gè)數(shù)的讀寫(xiě)線程              for(int i=0;i<threadNum;i++){                  se.execute(new Runnable(){                      public void run() {                          for(int i=0;i<round;i++){                              sumValue();                          }                           //每個(gè)線程執(zhí)行完同步方法后就等待                          try {                              cb.await();                          } catch (InterruptedException e) {                              // TODO Auto-generated catch block                              e.printStackTrace();                          } catch (BrokenBarrierException e) {                              // TODO Auto-generated catch block                              e.printStackTrace();                          }                        }                  });                  se.execute(new Runnable(){                      public void run() {                           getValue();                          try {                              //每個(gè)線程執(zhí)行完同步方法后就等待                              cb.await();                          } catch (InterruptedException e) {                              // TODO Auto-generated catch block                              e.printStackTrace();                          } catch (BrokenBarrierException e) {                              // TODO Auto-generated catch block                              e.printStackTrace();                          }                       }                  });              }               try {                  //當(dāng)前統(tǒng)計(jì)線程也wait,所以CyclicBarrier的初始值是threadNum*2+1                  cb.await();              } catch (InterruptedException e) {                  // TODO Auto-generated catch block                  e.printStackTrace();              } catch (BrokenBarrierException e) {                  // TODO Auto-generated catch block                  e.printStackTrace();              }              //所有線程執(zhí)行完成之后,才會(huì)跑到這一步              long duration=System.nanoTime()-start;              out.println(id+" = "+duration);           }       }

    補(bǔ)充知識(shí)

    CyclicBarrier和CountDownLatch一樣,都是關(guān)于線程的計(jì)數(shù)器。

    • CyclicBarrier初始化時(shí)規(guī)定一個(gè)數(shù)目,然后計(jì)算調(diào)用了CyclicBarrier.await()進(jìn)入等待的線程數(shù)。當(dāng)線程數(shù)達(dá)到了這個(gè)數(shù)目時(shí),所有進(jìn)入等待狀態(tài)的線程被喚醒并繼續(xù)。
    • CyclicBarrier就象它名字的意思一樣,可看成是個(gè)障礙, 所有的線程必須到齊后才能一起通過(guò)這個(gè)障礙。
    • CyclicBarrier初始時(shí)還可帶一個(gè)Runnable的參數(shù), 此Runnable任務(wù)在CyclicBarrier的數(shù)目達(dá)到后,所有其它線程被喚醒前被執(zhí)行。
    posted on 2016-12-14 14:26 jinfeng_wang 閱讀(165) 評(píng)論(0)  編輯  收藏 所屬分類: 2016-thread

    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 亚洲精品午夜久久久伊人| 在线视频观看免费视频18| 一级毛片视频免费观看| 国产精品亚洲专区无码不卡| 亚洲一级高清在线中文字幕| 亚洲人成在线播放| 亚洲成AV人片久久| 亚洲一级免费视频| 日韩亚洲不卡在线视频中文字幕在线观看 | 亚洲短视频男人的影院| 亚洲小说区图片区另类春色| 亚洲精品无码Av人在线观看国产| 国产精品亚洲高清一区二区| 国产亚洲人成网站在线观看| 国产亚洲情侣一区二区无| 国产亚洲精品精华液| 亚洲人成影院在线| 亚洲精品在线播放视频| 亚洲av无码不卡久久| 亚洲色大18成人网站WWW在线播放| 亚洲啪AV永久无码精品放毛片| 色偷偷亚洲第一综合| 夜夜爽妓女8888视频免费观看| 国产成人无码免费看片软件| 男人的天堂网免费网站| 亚洲成人免费在线观看| 女人18一级毛片免费观看| 免费看国产一级特黄aa大片| 亚洲色婷婷综合开心网| 久久精品国产亚洲香蕉| 亚洲成人福利网站| 久久精品国产亚洲AV电影网| 免费人成大片在线观看播放电影 | 久久精品国产亚洲| 亚洲午夜电影在线观看高清| 亚洲色偷偷色噜噜狠狠99网| 九九全国免费视频| 久久精品电影免费动漫| 好吊妞在线成人免费| 久久久久一级精品亚洲国产成人综合AV区| 亚洲国产精品无码久久一区二区|