首頁 >後端開發 >php教程 >使用synchronized實作一個Lock程式碼詳解

使用synchronized實作一個Lock程式碼詳解

php中世界最好的语言
php中世界最好的语言原創
2017-12-20 11:56:032516瀏覽

本文要為大家介紹如何使用synchronized實作Lock程式碼,以下是實戰案例,需要的朋友可以參考借鏡。

方式一:

public synchronized void a(){
  //TODO
}


方式二:

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


從這兩種方式來你看,鎖都是加在{}之間的,我們再來看看Lock是如何做的呢:

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


這種方式的鎖是加在lock( )和unlock()之間的,所以要實作一個lock功能,就要想怎麼實作這樣兩個方法,lock()和unlock()方法,先定義一個框架如下:

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

   


然後要想怎麼用synchronized去實作這兩個方法。

現在其實只是稍微清楚了一點思路,但是還不知道怎麼去填充這兩個方法,這是後再來分析一下Lock的加鎖有什麼特點,再來看看這段程式碼:

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
    }
}

   


這段程式碼我只是加了一點註釋,別的什麼都沒有做,是不是幫忙理解這段程式碼,看看出現頻率最高的字是什麼,是currentthread,那我們去填充lock()和unlock()方法的時候是不是注意到要抓住currentthread這個關鍵字就可以找到解決方案呢?答案是肯定的。

接著分析,使用synchronized的時候該如何讓執行緒等待呢?是用wait()方法。怎麼讓執行緒喚醒呢,是用notify()方法。那麼就要在lock()方法中使用wait()方法,在unlock()方法中使用notify()方法。那我們在使用wait()和notify()的時候是有一個條件的,想想我們應該用什麼作為條件呢?

我們應該使用當前鎖是否被佔用作為判斷條件,如果鎖被佔用,currentthread等待,想想我們在使用synchronized的時候是不是一直使用的這個條件,答案也是肯定的。

再來分析什麼時候釋放鎖,使用什麼作為條件,想想如果線程A拿到了鎖,線程B能釋放嗎?當然不能,如果B能釋放就違反了原則,當然不能。肯定是A線程的鎖只能A來釋放。所以判斷條件就是判斷持有鎖的執行緒是不是currentthread,如果是的話,可以釋放,不是的話當然不能。

現在來看看完整的程式碼:

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();
                }
            }
            );
        }
    }
}

   


#執行一下看看結果:

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循環改成30次,再看一下結果:

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


相信看了這些案例你已經掌握了方法,更多精彩請關注php中文網其它相關文章!

相關讀取:

php如何實作堆疊資料結構以及括號匹配演算法的程式碼範例詳解

php中最簡單的字串匹配演算法,php匹配演算法_PHP教程

最簡單的php中字串匹配演算法教程

以上是使用synchronized實作一個Lock程式碼詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn