<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      【轉(zhuǎn)】-synchronized與Lock的區(qū)別與使用

      詳解synchronized與Lock的區(qū)別與使用

      該博客轉(zhuǎn)載自?淳安郭富城??詳解synchronized與Lock的區(qū)別與使用

      1. 引言:

      昨天在學(xué)習(xí)別人分享的面試經(jīng)驗(yàn)時(shí),看到Lock的使用。想起自己在上次面試也遇到了synchronized與Lock的區(qū)別與使用。于是,我整理了兩者的區(qū)別和使用情況,同時(shí),對(duì)synchronized的使用過程一些常見問題的總結(jié),最后是參照源碼和說明文檔,對(duì)Lock的使用寫了幾個(gè)簡(jiǎn)單的Demo。請(qǐng)大家批評(píng)指正。

      1.1 技術(shù)點(diǎn):

      1.1.1 線程與進(jìn)程:

      在開始之前先把進(jìn)程與線程進(jìn)行區(qū)分一下,一個(gè)程序最少需要一個(gè)進(jìn)程,而一個(gè)進(jìn)程最少需要一個(gè)線程。關(guān)系是線程–>進(jìn)程–>程序的大致組成結(jié)構(gòu)。所以線程是程序執(zhí)行流的最小單位,而進(jìn)程是系統(tǒng)進(jìn)行資源分配和調(diào)度的一個(gè)獨(dú)立單位。以下我們所有討論的都是建立在線程基礎(chǔ)之上。

      1.1.2 Thread的幾個(gè)重要方法:

      我們先了解一下Thread的幾個(gè)重要方法。a、start()方法,調(diào)用該方法開始執(zhí)行該線程;b、stop()方法,調(diào)用該方法強(qiáng)制結(jié)束該線程執(zhí)行;c、join方法,調(diào)用該方法等待該線程結(jié)束。d、sleep()方法,調(diào)用該方法該線程進(jìn)入等待。e、run()方法,調(diào)用該方法直接執(zhí)行線程的run()方法,但是線程調(diào)用start()方法時(shí)也會(huì)運(yùn)行run()方法,區(qū)別就是一個(gè)是由線程調(diào)度運(yùn)行run()方法,一個(gè)是直接調(diào)用了線程中的run()方法!!

      看到這里,可能有些人就會(huì)問啦,那wait()和notify()呢?要注意,其實(shí)wait()與notify()方法是Object的方法,不是Thread的方法!!同時(shí),wait()與notify()會(huì)配合使用,分別表示線程掛起和線程恢復(fù)。

      這里還有一個(gè)很常見的問題,順帶提一下:wait()與sleep()的區(qū)別,簡(jiǎn)單來說wait()會(huì)釋放對(duì)象鎖而sleep()不會(huì)釋放對(duì)象鎖。這些問題有很多的資料,不再贅述。

      1.1.3 線程狀態(tài):

      線程總共有5大狀態(tài),通過上面第二個(gè)知識(shí)點(diǎn)的介紹,理解起來就簡(jiǎn)單了。

      新建狀態(tài):新建線程對(duì)象,并沒有調(diào)用start()方法之前

      就緒狀態(tài):調(diào)用start()方法之后線程就進(jìn)入就緒狀態(tài),但是并不是說只要調(diào)用start()方法線程就馬上變?yōu)楫?dāng)前線程,在變?yōu)楫?dāng)前線程之前都是為就緒狀態(tài)。值得一提的是,線程在睡眠和掛起中恢復(fù)的時(shí)候也會(huì)進(jìn)入就緒狀態(tài)哦。

      運(yùn)行狀態(tài):線程被設(shè)置為當(dāng)前線程,開始執(zhí)行run()方法。就是線程進(jìn)入運(yùn)行狀態(tài)

      阻塞狀態(tài):線程被暫停,比如說調(diào)用sleep()方法后線程就進(jìn)入阻塞狀態(tài)

      死亡狀態(tài):線程執(zhí)行結(jié)束

      1.1.4 鎖類型

      可重入鎖:在執(zhí)行對(duì)象中所有同步方法不用再次獲得鎖

      可中斷鎖:在等待獲取鎖過程中可中斷

      公平鎖: 按等待獲取鎖的線程的等待時(shí)間進(jìn)行獲取,等待時(shí)間長(zhǎng)的具有優(yōu)先獲取鎖權(quán)利

      讀寫鎖:對(duì)資源讀取和寫入的時(shí)候拆分為2部分處理,讀的時(shí)候可以多線程一起讀,寫的時(shí)候必須同步地寫

      2. synchronized與Lock的區(qū)別

      2.1 兩者區(qū)別

      類別 synchronized Lock
      存在層次 Java的關(guān)鍵字,在jvm層面上 是一個(gè)類
      鎖的釋放 1、以獲取鎖的線程執(zhí)行完同步代碼,釋放鎖
      2、線程執(zhí)行發(fā)生異常,jvm會(huì)讓線程釋放鎖
      在finally中必須釋放鎖,不然容易造成線程死鎖
      鎖的獲取 假設(shè)A線程獲得鎖,B線程等待。
      如果A線程阻塞,B線程會(huì)一直等待
      分情況而定,Lock有多個(gè)鎖獲取的方式,具體下面會(huì)說道
      大致就是可以嘗試獲得鎖,線程可以不用一直等待
      鎖狀態(tài) 無法判斷 可以判斷
      鎖類型 可重入 不可中斷 非公平 可重入 可判斷 可公平(兩者皆可)
      性能 少量同步 大量同步

      3. Lock詳細(xì)介紹與Demo

      以下是Lock接口的源碼,筆者修剪之后的結(jié)果:

      public interface Lock {
      
          /**
           * Acquires the lock.
           */
          void lock();
      
          /**
           * Acquires the lock unless the current thread is
           * {@linkplain Thread#interrupt interrupted}.
           */
          void lockInterruptibly() throws InterruptedException;
      
          /**
           * Acquires the lock only if it is free at the time of invocation.
           */
          boolean tryLock();
      
          /**
           * Acquires the lock if it is free within the given waiting time and the
           * current thread has not been {@linkplain Thread#interrupt interrupted}.
           */
          boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
      
          /**
           * Releases the lock.
           */
          void unlock();
      	
      }
      

      從Lock接口中我們可以看到主要有個(gè)方法,這些方法的功能從注釋中可以看出:

      • lock():獲取鎖,如果鎖被暫用則一直等待
      • unlock():釋放鎖
      • tryLock(): 注意返回類型是boolean,如果獲取鎖的時(shí)候鎖被占用就返回false,否則返回true
      • tryLock(long time, TimeUnit unit):比起tryLock()就是給了一個(gè)時(shí)間期限,保證等待參數(shù)時(shí)間
      • lockInterruptibly():用該鎖的獲得方式,如果線程在獲取鎖的階段進(jìn)入了等待,那么可以中斷此線程,先去做別的事

      通過 以上的解釋,大致可以解釋在上個(gè)部分中“鎖類型(lockInterruptibly())”,“鎖狀態(tài)(tryLock())”等問題,還有就是前面子所獲取的過程我所寫的“大致就是可以嘗試獲得鎖,線程可以不會(huì)一直等待”用了“可以”的原因。

      下面是Lock一般使用的例子,注意ReentrantLock是Lock接口的實(shí)現(xiàn)。
      lock():

      
      package com.brickworkers;
      
      import java.util.concurrent.locks.Lock;
      import java.util.concurrent.locks.ReentrantLock;
      
      public class LockTest {
      	private Lock lock = new ReentrantLock();
      
      	//需要參與同步的方法
      	private void method(Thread thread){
      		lock.lock();
      		try {
      			System.out.println("線程名"+thread.getName() + "獲得了鎖");
      		}catch(Exception e){
      			e.printStackTrace();
      		} finally {
      			System.out.println("線程名"+thread.getName() + "釋放了鎖");
      			lock.unlock();
      		}
      	}
      	
      	public static void main(String[] args) {
      		LockTest lockTest = new LockTest();
      		
      		//線程1
      		Thread t1 = new Thread(new Runnable() {
      			
      			@Override
      			public void run() {
      				lockTest.method(Thread.currentThread());
      			}
      		}, "t1");
      		
      		Thread t2 = new Thread(new Runnable() {
      			
      			@Override
      			public void run() {
      				lockTest.method(Thread.currentThread());
      			}
      		}, "t2");
      		
      		t1.start();
      		t2.start();
      	}
      }
      //執(zhí)行情況:線程名t1獲得了鎖
      //         線程名t1釋放了鎖
      //         線程名t2獲得了鎖
      //         線程名t2釋放了鎖
      
      

      tryLock():

      package com.brickworkers;
      
      import java.util.concurrent.locks.Lock;
      import java.util.concurrent.locks.ReentrantLock;
      
      public class LockTest {
      	private Lock lock = new ReentrantLock();
      
      	//需要參與同步的方法
      	private void method(Thread thread){
      /*		lock.lock();
      		try {
      			System.out.println("線程名"+thread.getName() + "獲得了鎖");
      		}catch(Exception e){
      			e.printStackTrace();
      		} finally {
      			System.out.println("線程名"+thread.getName() + "釋放了鎖");
      			lock.unlock();
      		}*/
      		
      		
      		if(lock.tryLock()){
      			try {
      				System.out.println("線程名"+thread.getName() + "獲得了鎖");
      			}catch(Exception e){
      				e.printStackTrace();
      			} finally {
      				System.out.println("線程名"+thread.getName() + "釋放了鎖");
      				lock.unlock();
      			}
      		}else{
      			System.out.println("我是"+Thread.currentThread().getName()+"有人占著鎖,我就不要啦");
      		}
      	}
      	
      	public static void main(String[] args) {
      		LockTest lockTest = new LockTest();
      		
      		//線程1
      		Thread t1 = new Thread(new Runnable() {
      			
      			@Override
      			public void run() {
      				lockTest.method(Thread.currentThread());
      			}
      		}, "t1");
      		
      		Thread t2 = new Thread(new Runnable() {
      			
      			@Override
      			public void run() {
      				lockTest.method(Thread.currentThread());
      			}
      		}, "t2");
      		
      		t1.start();
      		t2.start();
      	}
      }
      
      //執(zhí)行結(jié)果: 線程名t2獲得了鎖
      //         我是t1有人占著鎖,我就不要啦
      //         線程名t2釋放了鎖
      
      
      

      看到這里相信大家也都會(huì)使用如何使用Lock了吧,關(guān)于tryLock(long time, TimeUnit unit)和lockInterruptibly()不再贅述。前者主要存在一個(gè)等待時(shí)間,在測(cè)試代碼中寫入一個(gè)等待時(shí)間,后者主要是等待中斷,會(huì)拋出一個(gè)中斷異常,常用度不高,喜歡探究可以自己深入研究。

      前面比較重提到“公平鎖”,在這里可以提一下ReentrantLock對(duì)于平衡鎖的定義,在源碼中有這么兩段:

      
       /**
           * Sync object for non-fair locks
           */
          static final class NonfairSync extends Sync {
              private static final long serialVersionUID = 7316153563782823691L;
      
              /**
               * Performs lock.  Try immediate barge, backing up to normal
               * acquire on failure.
               */
              final void lock() {
                  if (compareAndSetState(0, 1))
                      setExclusiveOwnerThread(Thread.currentThread());
                  else
                      acquire(1);
              }
      
              protected final boolean tryAcquire(int acquires) {
                  return nonfairTryAcquire(acquires);
              }
          }
      
          /**
           * Sync object for fair locks
           */
          static final class FairSync extends Sync {
              private static final long serialVersionUID = -3000897897090466540L;
      
              final void lock() {
                  acquire(1);
              }
      
              /**
               * Fair version of tryAcquire.  Don't grant access unless
               * recursive call or no waiters or is first.
               */
              protected final boolean tryAcquire(int acquires) {
                  final Thread current = Thread.currentThread();
                  int c = getState();
                  if (c == 0) {
                      if (!hasQueuedPredecessors() &&
                          compareAndSetState(0, acquires)) {
                          setExclusiveOwnerThread(current);
                          return true;
                      }
                  }
                  else if (current == getExclusiveOwnerThread()) {
                      int nextc = c + acquires;
                      if (nextc < 0)
                          throw new Error("Maximum lock count exceeded");
                      setState(nextc);
                      return true;
                  }
                  return false;
              }
          }
      

      從以上源碼可以看出在Lock中可以自己控制鎖是否公平,而且,默認(rèn)的是非公平鎖,以下是ReentrantLock的構(gòu)造函數(shù):

         public ReentrantLock() {
              sync = new NonfairSync();//默認(rèn)非公平鎖
          }
      
      posted @ 2024-07-10 09:51  booleandev  閱讀(25)  評(píng)論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 97人妻成人免费视频| 免费无码av片在线观看中文| 亚洲欧美在线观看一区二区| 日本福利一区二区精品| 国产无套白浆一区二区| 青青青爽在线视频观看| 国产精品女视频一区二区| 久久精品国产亚洲夜色av| 日本高清aⅴ毛片免费| 亚洲中文字幕一区二区| 91精品国产午夜福利| 中文字幕日韩有码av| 亚洲免费视频一区二区三区| 亚洲av日韩av综合在线观看| 精品偷拍被偷拍在线观看| 99精品热在线在线观看视| 一面膜上边一面膜下边视频| 五月婷久久麻豆国产| 亚洲国产成人久久综合区| 起碰免费公开97在线视频| 亚洲黄色一级片在线观看| 大香伊蕉在人线国产免费| 亚洲精品欧美综合二区| 亚洲精品欧美综合二区| 日韩69永久免费视频| 国产高清在线男人的天堂| 内射干少妇亚洲69xxx| 欧美另类精品xxxx人妖| 秋霞在线观看秋| 国产女人喷潮视频免费 | 国产日韩av二区三区| 久久久久人妻一区精品| 亚洲综合色婷婷中文字幕| 日韩av一中美av一中文字慕 | 99中文字幕精品国产| 国产精品午夜av福利| 国产精品小一区二区三区| 一出一进一爽一粗一大视频| 亚洲综合中文字幕首页| 国产玖玖玖玖精品电影| 中文字幕久久波多野结衣av|