博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
EP37 Yield、Sleep
阅读量:6766 次
发布时间:2019-06-26

本文共 2116 字,大约阅读时间需要 7 分钟。

Thread.yield()

让步就是投降,让出CPU资源给其他线程。其他线程自然会抢占->开始执行。 比如让线程的run方法里执行打印动作,在被interrupt之前,每打印5次就yield():

//run()方法里执行的内容    System.out.println(getName() + "执行了" + ++i + "次");      if(i % 5 == 0) {// 被5整除时让步          Thread.yield();      } 复制代码

然后创建两个线程分别开始执行上面的run方法,执行100毫秒。

//t1,t2两个线程分别执行run(),执行100毫秒后中断。    t1.start();      t2.start();      Thread.sleep(100);        t1.interrupt();      t2.interrupt();复制代码

结果会发现,t1,t2交替着执行了。

t1执行了1次t1执行了2次t1执行了3次t1执行了4次t1执行了5次t2执行了1次t2执行了2次t2执行了3次t2执行了4次t2执行了5次t1执行了6次t1执行了7次...复制代码

这就是线程让步(Yield)了。 这个看起来跟sleep是有点像的,sleep也是让出CPU资源,本线程不执行,其他线程抢占。但sleep到了期限就会醒过来的。yield只能等下次别人再yield才会醒过来。

Thread.sleep()

sleep需要注意一点,就是sleep过程中持有锁。

锁是怎么获得的?每个对象都有一个锁,线程访问synchronized方法/代码块的时候会获得锁。有了锁,别的线程再来访问就只能阻塞住,等待前人执行完了synchronized之后释放锁。

也就是说,如果一个进程是synchronized方法中sleep,即便它在睡觉中,别的线程依旧不能执行这个synchronized方法的。但可以执行这个类的其他方法。这就是互斥

Thread.sleep和Object.lock

sleep()睡眠时,占有对象锁; 而wait()睡眠时,释放对象锁。 为什么呢?可以考虑,sleep是Thread的static类,不能改变Object类的锁。所以不能释放锁。

wait睡眠的时候,wait所在的对象会进入于它相关的线程池,其他线程可以访问这个对象;等wait的时间结束了,或者被interrupt了,或者notify了,再从线程池里唤醒它,同时重新获取到对象的锁。

举个例子,

int number = 10;        ThreadTest threadTest = new ThreadTest();        Thread thread = new Thread(threadTest);        thread.start();        threadTest.secondMethod();复制代码

首先看看上面这段话的执行顺序,帅哥说,顺序是: thread.start();-->threadTest.secondMethod();--> thread里的run方法 笑哥说: thread.start(); 然后threadTest.secondMethod();和 thread里的run方法的话,这两个看CPU资源谁抢到了。 按照网上的说法是,先执行第主线程中的方法,也就是先执行secondMethod(); secondMethod中执行sleep或者wait:

public void secondMethod() throws Exception {        synchronized (this) {            Thread.sleep(2000);            //this.wait(2000);            number *= 200;        }    }复制代码

run()方法里执行:

@Override    public void run() {        try {            synchronized (this) {            number += 100;            System.out.println(number);        }              } catch (Exception e) {            e.printStackTrace();        }    }复制代码

sleep和wait的执行区别是,sleep输出2100,wait输出110。这是因为,sleep过程中要等sleep完了,执行了number *= 200;然后才继续执行number += 100;。wait就不会一直拿着锁,所以thread线程先去执行number += 100;了。

转载于:https://juejin.im/post/5a3132f25188257dd239a633

你可能感兴趣的文章
【WPF】C#代码动态添加控件的Margin属性
查看>>
redis info 参数详解
查看>>
UITableView刷新数据reLoadData
查看>>
基础太差了
查看>>
高性能服务器负载均衡的一个可行方案
查看>>
CSS布局
查看>>
按钮模式来自官方的 windows 7 快捷键大全
查看>>
《JAVA与模式》之单例模式(转载)
查看>>
ajax中的异步机制导致的问题
查看>>
java质数判断
查看>>
Android JNI和NDK学习(03)--动态方式实现JNI(转)
查看>>
如何提升你的面试机会?
查看>>
如何在Kubernetes部署期间正确处理DB模式
查看>>
甲骨文11.9亿美元收云解决方案供应商Aconex,预计明年上半年完成
查看>>
Python 做图片清晰度识别
查看>>
硬核NeruIPS 2018最佳论文,一个神经了的常微分方程
查看>>
个推Node.js 微服务实践:基于容器的一站式命令行工具链
查看>>
Express源码学习-路由篇
查看>>
Android平台上图片/视频选择,编辑和压缩的一站式解决方案
查看>>
从零开始撸一个Fresco之总结
查看>>