线程间的通信

线程间进行通信,简单的方法可以有利用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 {

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