線程間的通信

線程間進行通信,簡單的方法可以有利用synchronized來同步某個數據標誌,一個線程負責設置標誌,另一個線程負責循環檢測該標誌,這種方法的好處時方便,但是需要輪訓,消耗太多的cpu時間。那有人說,可以使用sleep,每sleep一毫秒,檢測一次,這樣就不用消耗太多cpu時間了,這種方法是不錯,若是沒有明顯的低延遲要求,真的可以的。但若是對於sleep有時間要求呢,希望儘快,而不是一個固定時間呢,這時候就最好使用java提供的線程通信機制。
線程通信,主要利用的是notify和wait方法。
通過對同一個對象的wait方法調用,可以讓當前線程進入等待狀態,對該對象的notify方法調用,則可以讓在該對象上進入wait等待狀態的一個隨機線程被喚醒繼續工作。notifyall則可以調用所有。
有這樣一個以synchronized和notify/wait結合來製作一個簡單的Lock的代碼:

package Thread_03;

import java.util.List;
import java.util.Optional;
import java.util.ArrayList;
import java.util.Collections;
import java.util.concurrent.TimeoutException;
import static java.lang.Thread.currentThread;
import static java.lang.System.currentTimeMillis;
/*
 * 用synchronized 和 Object的對象的wait和notify。 來開發一個精簡版的lock。
 * 
 */
interface Lock
{
    void lock() throws InterruptedException;
    void lock(long mills) throws InterruptedException,TimeoutException;
    void unlock();
    List<Thread> getBlockedThreads();

}

class BooleanLock implements Lock
{
    private Thread currentThread;
    private boolean locked = false;
    private final List<Thread> blockedList = new ArrayList<>();
    @Override
    public void lock() throws InterruptedException {
        synchronized(this)
        {
            while(locked)
            {
                if(!blockedList.contains(currentThread()))
                    blockedList.add(currentThread());
                this.wait();
            }
            blockedList.remove(currentThread());
            this.locked = true;
            this.currentThread = currentThread();
        }

    }

    @Override
    public void lock(long mills) throws InterruptedException, TimeoutException {
        synchronized(this)
        {
            if(mills<0)
            {
                this.lock();
            }
            else
            {
                long remainingMills = mills;
                long endMills = currentTimeMillis() + remainingMills;
                while(locked)
                {
                    if(remainingMills <= 0)
                        throw new TimeoutException("can not get lock : wait time out");
                    if(!blockedList.contains(currentThread()))
                        blockedList.add(currentThread());
                    this.wait(remainingMills);
                    remainingMills = endMills - currentTimeMillis();
                }
                blockedList.remove(currentThread());
                this.locked = true;
                this.currentThread = currentThread();
            }
        }
    }
    @Override
    public void unlock() {
        synchronized(this)
        {
            if(currentThread == currentThread())
            {
                this.locked = false;
                //Optional.of("dd").ifPresent(System.out::println);
                this.notifyAll();
            }
        }

    }
    @Override
    public List<Thread> getBlockedThreads() {

        return Collections.unmodifiableList(blockedList);
    }

}

public class notifyWaitStudy {

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章