(四)使用好多线程挂起suspend和继续执行resume

之前介绍了多线程的挂起suspend()和继续执行resume()
也说了他的弊端,不建议使用是一回事,但是并不影响我们去了解他们
下面我们说一下 如何规避其弊端,更好的使用他
这里也就结合了多线程的等待wait() 和唤醒notify()

package com.zmkj.admin.test;

/**
 *
 * SuspendAndResume  挂起 和 继续执行的问题
 * 这里说一下 如何 搞一个比较靠谱的Suspend 方法
 *
 * @author sunminghao
 */
public class GoodSuspend {
    public static Object u = new Object();

    public static class ChangeObjectThread extends Thread{
        //表示当前线程是否被挂起
        //关于volatile 关键词的讲解 https://www.cnblogs.com/dolphin0520/p/3920373.html
        volatile boolean suspendme = false;

        public void suspendMe() {
            suspendme = true;
        }

        public void resumeMe() {
            suspendme = false;
            synchronized (this){
                //唤醒线程继续执行
                notify();
            }
        }

        @Override
        public void run() {
            while (true) {
                //线程会先检查自己是否被挂起,是,执行wait 进行等待
                synchronized (this){
                    while (suspendme) {
                        try {
                            //使线程等待,等待唤醒操作
                            wait();
                            System.out.println("wait ==========================================================");
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }

                synchronized (u){
                    System.out.println("in ChangeObjectThread");
                }

                //Thread.yield() 方法,使当前线程由执行状态,变成为就绪状态,让出cpu时间,在下一个线程执行时候,此线程有可能被执行,也有可能没有被执行。
                Thread.yield();
            }
        }
    }


    public static class ReadObjectThread extends Thread{

        @Override
        public void run() {
            while (true){
                synchronized (u) {
                    System.out.println("in ReadObjectThread。。。。。。。。");
                }
                Thread.yield();
            }
        }
    }


    public static void main(String[] args) throws InterruptedException {
        ChangeObjectThread t1 = new ChangeObjectThread();
        ReadObjectThread t2 = new ReadObjectThread();
        t1.start();
        t2.start();
        Thread.sleep(1000);
        t1.suspendMe();
        System.out.println("suspend t1 2 sec");
        Thread.sleep(15000);
        System.out.println("resume t1");
        //上面线程没有挂起,则执行到这里,执行notify方法,并清除挂起标记,从而正常执行。
        t1.resumeMe();
    }

    /**
     * 一、volatile 的特性
     *
     * 1、保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。(实现可见性)
     * 2、禁止进行指令重排序。(实现有序性)
     * 3、volatile 只能保证对单次读/写的原子性。i++ 这种操作不能保证原子性。
     * 关于volatile 原子性可以理解为把对volatile变量的单个读/写,看成是使用同一个锁对这些单个读/写操作做了同步,就跟下面的SoWhat跟SynSoWhat功能类似哦。
     *
     * 二、Thread.yield() 方法
     * 使当前线程由执行状态,变成为就绪状态,让出cpu时间,在下一个线程执行时候,此线程有可能被执行,也有可能没有被执行。
     *
     *
     * 项目测试过程:
     * 1、debugger   t1.resumeMe();
     * 2、控制台在不断的输出
     *          in ChangeObjectThread
     *          in ReadObjectThread。。。。。。。。
     *  说明两个线程都在执行;
     *  当我们执行到 方法 t1.suspendMe() 时,这里将 suspendme = true 这里会触发t1.wait()方法,将线程t1挂起,处于等待的状态;
     * 3、这个时候控制台一直在输出
     *          in ReadObjectThread。。。。。。。。
     *   说明t1 的线程不再被执行,t2 线程可以放肆的输出
     *
     * 4、当执行到 t1.resumeMe() 方法时,
     * (我们有断点,这里我们采用一步一步的执行 效果成明显,要不然控制台很快就被刷满了 会看不到重要的一部分日志)
     * (这里我们也可以在 wait() 方法之后的日志输出这一行再打上断点 会看的更直观)
     *  notif()唤醒了之前被wait的线程,这时候,控制台 就又变成了  ChangeObjectThread 和 ReadObjectThread 交互输出了
     *
     * 同时也发现  "wait ================================" 这个日志输出,是在 执行了 notify 方法之后才被输出,
     * 这样就说明了:线程在 被方法wait 暂停之后,就不再继续执行,而是在被 notify 方法唤醒之后,再继续向下执行
     *
     *
     *
     *
     */
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java程序源

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值