保护性暂停模式

157 阅读1分钟

import lombok.extern.slf4j.Slf4j;

import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
public class Test6 {
    public static void main(String[] args) {

        //test1();

        test2();
    }

    private static void test2() {
        for (int i = 0; i < 3; i++) {
            new People().start();
        }
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        for (Integer id : Mailboxes.getIds()) {
            new Postman(id,"内容"+id).start();
        }

    }


    /**
     * 保护性暂停模式
     */
    private static void test1() {

        GuardedObject guardedObject = new GuardedObject(12);

        //线程1等待线程2的结果
        new Thread(() -> {
            //等待结果
            log.info("等待结果");
            Object o = guardedObject.get(1000);
            log.info("返回结果是:{}",o);
        },"t1").start();

        new Thread(() -> {
            //执行任务
            log.info("执行任务");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //返回结果
            guardedObject.complete("answer");

        },"t2").start();
    }




    /**
     * blocked 是等待锁的状态
     * waiting 是等待被唤醒的状态,唤醒后会重新进入entryList竞争锁
     *
     *   object类的方法,必须是持锁的线程才能调用
     * wait
     * notify
     * notifyAll
     */

}
 class GuardedObject{

    public GuardedObject(int id) {
        this.id = id;
    }

    private int id;

    public int getId() {
        return id;
    }

    //结果
    private Object response;
    //获取结果
    public Object get(long timeout) {
        synchronized (this) {
            // 开始时间
            long begin = System.currentTimeMillis();
            //经历的时间
            long passTime = 0;
            while (response == null) {
                //应该等待的时间
                long waitTime = timeout - passTime;
                //经历的时间超过了最大等待时间,退出循环
                if (waitTime<=0) {
                    break;
                }
                try {
                    this.wait(waitTime); //虚假唤醒的问题
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                passTime = System.currentTimeMillis()-begin;
            }
            return response;
        }
    }
    //产生结果
    public void complete(Object response) {
        synchronized (this) {
            this.response = response;
            this.notifyAll();
        }
    }
}

@Slf4j
class People extends Thread{
    @Override
    public void run() {
        //收信
        GuardedObject guardedObject = Mailboxes.createGuardedObject();
        log.info("收信:{}",guardedObject.getId());
        Object mail = guardedObject.get(5000);
        log.info("收到信:{},内容为:{}",guardedObject.getId(),mail);

    }
}

@Slf4j
class Postman extends Thread {
    private int id ;
    private String mail;

    public Postman(int id, String mail) {
        this.id = id;
        this.mail = mail;
    }

    @Override
    public void run() {
        log.info("送信id:{} , 内容:{}",id,mail);
        Mailboxes.getGuardedObject(id).complete(mail);
    }
}

class Mailboxes{
    private static   Map<Integer, GuardedObject> boxes = new ConcurrentHashMap<>();
    private static int id = 1;
    public static synchronized int generateId() {
        return id++;
    }

    public static GuardedObject createGuardedObject() {
        GuardedObject go = new GuardedObject(generateId());
        boxes.put(go.getId(), go);
        return go;
    }

    public  static Set<Integer> getIds() {
        return boxes.keySet();
    }

    public static  GuardedObject getGuardedObject(int id) {
        return boxes.remove(id);
    }


}