Guarded Suspension 模式

适用的情况

相比于Single Thread Exception模式, 本模式加入了加入了守护条件来确保共享实例在被线程访问前是正确的状态

实现的方式

如果实例是不正确的, 那么就让前来访问的线程执行wait(), 在线程恢复到正确状态的时候, 由持有锁的进程来唤醒等待的线程继续访问被守护的实例.
线程恢复到正确状态的时候, 一定要执行notify()或notifyAll(),否则等待的线程将永远无法被唤醒!

相关的模式

  • Single Thread Exception模式的升级版, 增加了守护条件!
  • 如果希望在实例是非正确的条件下, 来访问的线程不进行等待, 而是直接返回, 可以使用Balking模式

代码示例:

package com.graphic.guardedSuspension;

import java.util.LinkedList;
import java.util.Queue;
import java.util.Random;

/**
 * @author youngxinler  19-5-19 下午8:45
 * @version 0.1
 **/

public class RequestQueue {
    private final Queue requestQueue = new LinkedList();

    public synchronized Request getRequest(){
        while (requestQueue.peek() == null){
            try {
                wait();
            }catch (InterruptedException e){
                e.printStackTrace();
            }
        }
        return requestQueue.remove();
    }

    public synchronized void putRequest(Request request){
        requestQueue.add(request);
        notifyAll();
    }
}

package com.graphic.guardedSuspension;

/**
 * @author youngxinler  19-5-19 下午8:37
 * @version 0.1
 **/

public class Request {
    private final String name;

    public Request(String name){
        this.name = name;
    }

    public String getName(){
        return name;
    }

    public String toString(){
        return "[ Request" + name + " ]";
    }
}

package com.graphic.guardedSuspension;

import java.util.Random;

/**
 * @author youngxinler  19-5-19 下午9:00
 * @version 0.1
 **/

public class ServerThread extends Thread{
    private final Random random;
    private final RequestQueue requestQueue;

    public ServerThread(String name, long seed, RequestQueue requestQueue){
        super(name);
        this.random = new Random(seed);
        this.requestQueue = requestQueue;
    }

    @Override
    public void run(){
        for (int i = 0; i < 10000; i++) {
            Request request = requestQueue.getRequest();
            System.out.println(Thread.currentThread().getName() + " request " + request);
            try{
                Thread.sleep(random.nextInt(1000));
            }catch (InterruptedException e){
                e.printStackTrace();
            }
        }
    }
}

package com.graphic.guardedSuspension;

import java.util.Random;

/**
 * @author youngxinler  19-5-19 下午8:55
 * @version 0.1
 **/

public class ClientThread extends Thread {
    private final Random random;
    private final RequestQueue requestQueue;

    public ClientThread(String s, long seed, RequestQueue requestQueue) {
        super(s);
        this.random = new Random(seed);
        this.requestQueue = requestQueue;
    }

    @Override
    public void run(){
        for (int i = 0; i < 10000; i++) {
            Request request = new Request("No," + i);
            System.out.println(Thread.currentThread().getName() + " request " + request);
            requestQueue.putRequest(request);
            try {
                Thread.sleep(random.nextInt(1000));
            }catch (InterruptedException e){
                e.printStackTrace();
            }
        }
    }
}


package com.graphic.guardedSuspension;

/**
 * @author youngxinler  19-5-19 下午9:05
 * @version 0.1
 **/

public class Main {
    private static final String url = "";
    public static void main(String[] args) {
        RequestQueue requestQueue = new RequestQueue();
        new ClientThread("alice", 5451L, requestQueue);
        new ServerThread("bob", 1651531L, requestQueue);
    }
}

点我,12种Java多线程设计模式, 希望能帮到你

你可能感兴趣的:(Guarded Suspension 模式)