读《图解java多线程设计模式》总结--Guarded Suspension

1,从名字上看就是增加了守护功能的一种设计模式,目的是确保在多线程条件下各线程能正常操作共享资源,如果触发了守护功能,相关的线程就必须等待,直到守护功能确保不会出现操作异常才会让线程继续执行下去。

2,与Single Threaded Execution 相似都是为了保护共享资源,只不过Single Threaded Execution是无条件的多线程互斥,而Guarded Suspension是在守护条件不满足的情况下才会使得相关的线程进入等待。

3,实现方式,这里有几个概念,一个是守护方法(GuardedMethod),该方法只有在守护条件满足的情况下才会执行对共享资源的操作,如果不满足守护条件,则让调用该方法线程一直等待,守护方法是通过while和wait实现。另一个是改变守护条件方法(StateChangeingMethod),该方法由另外一个线程调用,改变守护条件,使得守护方法里面能够满足守护条件,而让等待的线程继续执行下去,改变守护条件方法是通过notify/notifyAll来实现

4,代码实现

1)先定义一个Guard类,里面分别实现GuardedMethod和StateChangeingMethod,GuardedMethod的守护条件是共享资源的值等于5,如果不等于5就让当前线程一直等待

package guardesuspension.study;

public class Guard {

    int sharedResource=0;
    public synchronized void  guardedMethod()
    {
        while(sharedResource!=5)
        {
            System.out.println("Thread name:"+Thread.currentThread().getName()+" is waiting");
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("Thread name:"+Thread.currentThread().getName()+" read shared resource:"+ sharedResource);
    }


    public synchronized void  stateChangeingMethod()
    {
        sharedResource=5;
        System.out.println("Thread name:"+Thread.currentThread().getName()+" set shared resource:"+ sharedResource);
        notifyAll();
    }
}

 

2)启动两条线程,线程1调用GuardedMethod,由于不满足守护条件,线程1被阻塞,2秒后,线程2调用stateChangeingMethod,改变共享资源的值,并且通知线程1,此时线程1的守护条件满足了,不再等待,继续执行下面的程序

package guardesuspension.study;

public class GuardedSuspension {

    public static void main(String[] args) {
        Guard guard=new Guard();

        Thread thead1=new Thread(
                new Runnable() {
                    @Override
                    public void run() {
                        guard.guardedMethod();
                    }
                }
        );
        thead1.start();


        Thread thead2=new Thread(
                new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Thread.sleep(2000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        guard.stateChangeingMethod();
                    }
                }
        );
        thead2.start();

    }
}

3)执行结果

Thread name:Thread-0 is waiting    //线程0不满足守护条件,进入等待
Thread name:Thread-1 set shared resource:5  //线程1改变了守护条件,并通知线程0
Thread name:Thread-0 read shared resource:5 //此时线程0满足了守护条件不等待,执行等待后的程序

 

5,Java类库中的应用

java.util.LinkedBlockingQueue采用的就是Guarded Suspension模式

该类有两个相关方法

一个是take()获取队首元素,如果此时队列是空,那么调用take方法的线程就会进入等待。

一个是put ()往对列末尾添加元素,添加完后会让由于调用take进入等待的线程继续执行,获取到队首元素

LinkedBlockingQueue已经实现了线程等待功能,所以不需要使用wait, notify,notifyAll等线程同步方法

1)具体代码实例

package guardesuspension.study;

import java.util.concurrent.LinkedBlockingQueue;

public class LinkedBlockingQueueTest {

    public static void main(String[] args) {
        LinkedBlockingQueue<Integer> queue=new   LinkedBlockingQueue<Integer>(100);

        Thread thead1=new Thread(
                new Runnable() {
                    @Override
                    public void run() {
                        try {
                            System.out.println("Thread name:"+Thread.currentThread().getName()+" Get first from quene");
                           int result= queue.take();
                            System.out.println("Thread name:"+Thread.currentThread().getName()+" Get first from quene the result="+result);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
        );
        thead1.start();


        Thread thead2=new Thread(
                new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Thread.sleep(2000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }

                        try {
                            System.out.println("Thread name:"+Thread.currentThread().getName()+" Put value to quene");
                            queue.put(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }

                    }
                }
        );
        thead2.start();

    }

}


2)执行结果
Thread name:Thread-0 Get first from quene //线程0想获取队首元素,由于此时为空,线程进入等待
Thread name:Thread-1 Put value to quene //线程1把一个元素推入队列
Thread name:Thread-0 Get first from quene the result=100 //线程0继续执行,获取到队首元素

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值