溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

如何使用synchronized實(shí)現(xiàn)一個(gè)Lock

發(fā)布時(shí)間:2021-08-06 10:54:17 來(lái)源:億速云 閱讀:302 作者:小新 欄目:編程語(yǔ)言

這篇文章主要為大家展示了“如何使用synchronized實(shí)現(xiàn)一個(gè)Lock”,內(nèi)容簡(jiǎn)而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“如何使用synchronized實(shí)現(xiàn)一個(gè)Lock”這篇文章吧。

方式一:

public synchronized void a(){ 
  //TODO 
}

方式二:

public void b(){ 
  synchronized(this){ 
    //TODO 
  } 
}

從這兩種方式來(lái)看,鎖都是加在{}之間的,我們?cè)賮?lái)看看Lock是如何做的呢:

public void c() { 
  lock.lock(); 
  try { 
    // TODO 
  } finally { 
    lock.unlock(); 
  } 
}

這種方式的鎖是加在lock()和unlock()之間的,所以要想實(shí)現(xiàn)一個(gè)lock功能,就要想怎么實(shí)現(xiàn)這樣兩個(gè)方法,lock()和unlock()方法,先定義一個(gè)框架如下所示:

public void lock(){
}
public void unlock(){
}

然后要想怎么用synchronized去實(shí)現(xiàn)這兩個(gè)方法。

現(xiàn)在其實(shí)只是稍微清楚了一點(diǎn)思路,但是還不知道怎么去填充這兩個(gè)方法,這是后再來(lái)分析一下Lock的加鎖有什么特點(diǎn),再來(lái)看看這段代碼:

public void c() {
	lock.lock();
	//When current thread get the lock, other thread has to wait 
	try {
		//current thread get in the lock, other thread can not get in 
		// TODO
	}
	finally {
		lock.unlock();
		//current thread release the lock
	}
}

這段代碼我只是加了一點(diǎn)注釋,別的什么都沒有做,是不是幫助理解這段代碼,看看出現(xiàn)頻率最高的詞是什么,是currentthread,那么我們?nèi)ヌ畛鋖ock()和unlock()方法的時(shí)候是不是注意要抓住currentthread這個(gè)關(guān)鍵字就可以找到解決方案呢?答案是肯定的。

接著分析,使用synchronized的時(shí)候如何讓線程等待呢?是用wait()方法。怎么讓線程喚醒呢,是用notify()方法。那么就要在lock()方法中使用wait()方法,在unlock()方法中使用notify()方法。那么我們?cè)谑褂脀ait()和notify()的時(shí)候是有一個(gè)條件的,想想我們應(yīng)該使用什么作為條件呢?

我們應(yīng)該使用當(dāng)前鎖是否被占用作為判斷條件,如果鎖被占用,currentthread等待,想想我們?cè)谑褂胹ynchronized的時(shí)候是不是一直使用的這個(gè)條件,答案也是肯定的。

再來(lái)分析一下什么時(shí)候釋放鎖,使用什么作為條件,想想如果線程A拿到了鎖,線程B能釋放嗎?當(dāng)然不能,如果B能釋放就違反了原則,當(dāng)然不能??隙ㄊ茿線程的鎖只能A來(lái)釋放。所以判斷條件就是判斷持有鎖的線程是不是currentthread,如果是的話,可以釋放,不是的話當(dāng)然不能。

現(xiàn)在來(lái)看看完整的代碼:

package test.lock;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
public class NaiveLock {
	private static final long NONE = -1;
	private long owner = NONE;
	private Boolean isLooked() {
		return owner != NONE;
	}
	public synchronized void lock() {
		long currentThreadId = Thread.currentThread().getId();
		if (owner == currentThreadId) {
			throw new IllegalStateException("Lock has been acquired by current thread");
		}
		while (this.isLooked()) {
			System.out.println(String.format("thread %s is waitting lock", currentThreadId));
			try {
				wait();
			}
			catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		owner = currentThreadId;
		System.out.println(String.format("Lock is acquired by thread %s", owner));
	}
	public synchronized void unlock() {
		if (!this.isLooked() || owner != Thread.currentThread().getId()) {
			throw new IllegalStateException("Only Lock owner can unlock the lock");
		}
		System.out.println(String.format("thread %s is unlocking", owner));
		System.out.println();
		owner = NONE;
		notify();
	}
	public static void main(String[] args) {
		final NaiveLock lock = new NaiveLock();
		ExecutorService executor = Executors.newFixedThreadPool(20, new ThreadFactory() {
			private ThreadGroup group = new ThreadGroup("test thread group");
			{
				group.setDaemon(true);
			}
			@Override 
			      public Thread newThread(Runnable r) {
				return new Thread(group, r);
			}
		}
		);
		for (int i = 0; i < 20; i++) {
			executor.submit(new Runnable() {
				@Override 
				        public void run() {
					lock.lock();
					System.out.println(String.format("thread %s is running...", Thread.currentThread().getId()));
					try {
						Thread.sleep(new Random().nextint(1000));
					}
					catch (InterruptedException e) {
						e.printStackTrace();
					}
					lock.unlock();
				}
			}
			);
		}
	}
}

運(yùn)行一下看看結(jié)果:

Lock is acquired by thread 8 
thread 8 is running... 
thread 27 is waitting lock 
thread 26 is waitting lock 
thread 25 is waitting lock 
thread 24 is waitting lock 
thread 23 is waitting lock 
thread 22 is waitting lock 
thread 21 is waitting lock 
thread 20 is waitting lock 
thread 19 is waitting lock 
thread 18 is waitting lock 
thread 17 is waitting lock 
thread 16 is waitting lock 
thread 15 is waitting lock 
thread 14 is waitting lock 
thread 13 is waitting lock 
thread 12 is waitting lock 
thread 11 is waitting lock 
thread 10 is waitting lock 
thread 9 is waitting lock 
thread 8 is unlocking 
 
Lock is acquired by thread 27 
thread 27 is running... 
thread 27 is unlocking 
 
Lock is acquired by thread 26 
thread 26 is running... 
thread 26 is unlocking 
 
Lock is acquired by thread 25 
thread 25 is running... 
thread 25 is unlocking 
 
Lock is acquired by thread 24 
thread 24 is running... 
thread 24 is unlocking 
 
Lock is acquired by thread 23 
thread 23 is running... 
thread 23 is unlocking 
 
Lock is acquired by thread 22 
thread 22 is running... 
thread 22 is unlocking 
 
Lock is acquired by thread 21 
thread 21 is running... 
thread 21 is unlocking 
 
Lock is acquired by thread 20 
thread 20 is running... 
thread 20 is unlocking 
 
Lock is acquired by thread 19 
thread 19 is running... 
thread 19 is unlocking 
 
Lock is acquired by thread 18 
thread 18 is running... 
thread 18 is unlocking 
 
Lock is acquired by thread 17 
thread 17 is running... 
thread 17 is unlocking 
 
Lock is acquired by thread 16 
thread 16 is running... 
thread 16 is unlocking 
 
Lock is acquired by thread 15 
thread 15 is running... 
thread 15 is unlocking 
 
Lock is acquired by thread 14 
thread 14 is running... 
thread 14 is unlocking 
 
Lock is acquired by thread 13 
thread 13 is running... 
thread 13 is unlocking 
 
Lock is acquired by thread 12 
thread 12 is running... 
thread 12 is unlocking 
 
Lock is acquired by thread 11 
thread 11 is running... 
thread 11 is unlocking 
 
Lock is acquired by thread 10 
thread 10 is running... 
thread 10 is unlocking 
 
Lock is acquired by thread 9 
thread 9 is running... 
thread 9 is unlocking

如果把for循環(huán)改成30次,再看一下結(jié)果:

Lock is acquired by thread 8 
thread 8 is running... 
thread 27 is waitting lock 
thread 26 is waitting lock 
thread 25 is waitting lock 
thread 24 is waitting lock 
thread 23 is waitting lock 
thread 22 is waitting lock 
thread 21 is waitting lock 
thread 20 is waitting lock 
thread 19 is waitting lock 
thread 18 is waitting lock 
thread 17 is waitting lock 
thread 16 is waitting lock 
thread 15 is waitting lock 
thread 14 is waitting lock 
thread 13 is waitting lock 
thread 12 is waitting lock 
thread 11 is waitting lock 
thread 10 is waitting lock 
thread 9 is waitting lock 
thread 8 is unlocking 
 
Lock is acquired by thread 27 
thread 27 is running... 
thread 8 is waitting lock 
thread 27 is unlocking 
 
Lock is acquired by thread 27 
thread 27 is running... 
thread 26 is waitting lock 
thread 27 is unlocking 
 
Lock is acquired by thread 27 
thread 27 is running... 
thread 25 is waitting lock 
thread 27 is unlocking 
 
Lock is acquired by thread 24 
thread 24 is running... 
thread 27 is waitting lock 
thread 24 is unlocking 
 
Lock is acquired by thread 23 
thread 23 is running... 
thread 24 is waitting lock 
thread 23 is unlocking 
 
Lock is acquired by thread 22 
thread 22 is running... 
thread 23 is waitting lock 
thread 22 is unlocking 
 
Lock is acquired by thread 22 
thread 22 is running... 
thread 21 is waitting lock 
thread 22 is unlocking 
 
Lock is acquired by thread 22 
thread 22 is running... 
thread 20 is waitting lock 
thread 22 is unlocking 
 
Lock is acquired by thread 22 
thread 22 is running... 
thread 19 is waitting lock 
thread 22 is unlocking 
 
Lock is acquired by thread 22 
thread 22 is running... 
thread 18 is waitting lock 
thread 22 is unlocking 
 
Lock is acquired by thread 17 
thread 17 is running... 
thread 17 is unlocking 
 
Lock is acquired by thread 16 
thread 16 is running... 
thread 16 is unlocking 
 
Lock is acquired by thread 15 
thread 15 is running... 
thread 15 is unlocking 
 
Lock is acquired by thread 14 
thread 14 is running... 
thread 14 is unlocking 
 
Lock is acquired by thread 13 
thread 13 is running... 
thread 13 is unlocking 
 
Lock is acquired by thread 12 
thread 12 is running... 
thread 12 is unlocking 
 
Lock is acquired by thread 11 
thread 11 is running... 
thread 11 is unlocking 
 
Lock is acquired by thread 10 
thread 10 is running... 
thread 10 is unlocking 
 
Lock is acquired by thread 9 
thread 9 is running... 
thread 9 is unlocking 
 
Lock is acquired by thread 8 
thread 8 is running... 
thread 8 is unlocking 
 
Lock is acquired by thread 26 
thread 26 is running... 
thread 26 is unlocking 
 
Lock is acquired by thread 25 
thread 25 is running... 
thread 25 is unlocking 
 
Lock is acquired by thread 27 
thread 27 is running... 
thread 27 is unlocking 
 
Lock is acquired by thread 24 
thread 24 is running... 
thread 24 is unlocking 
 
Lock is acquired by thread 23 
thread 23 is running... 
thread 23 is unlocking 
 
Lock is acquired by thread 21 
thread 21 is running... 
thread 21 is unlocking 
 
Lock is acquired by thread 20 
thread 20 is running... 
thread 20 is unlocking 
 
Lock is acquired by thread 19 
thread 19 is running... 
thread 19 is unlocking 
 
Lock is acquired by thread 18 
thread 18 is running... 
thread 18 is unlocking

以上是“如何使用synchronized實(shí)現(xiàn)一個(gè)Lock”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI