休眠

  在Java多线程中,可以使用sleep()方法在指定毫秒数内让当前正在执行的线程休眠。

  下面这段代码,使得主函数的main线程休眠了2000ms,最后输出的间隔时间也是2000ms。

  1. public class MyThread extends Thread {
  2. public static void main(String[] args) {
  3. try {
  4. long begin;
  5. long end;
  6. begin = System.currentTimeMillis();
  7. System.out.println("begin = " + begin);
  8. Thread.sleep(2000);
  9. end = System.currentTimeMillis();
  10. System.out.println("end = " + end);
  11. System.out.println("end - begin = " + (end - begin) + "ms");
  12. } catch (InterruptedException e) {
  13. e.printStackTrace();
  14. }
  15. }
  16. }

输出结果:

begin = 1486711105366

end = 1486711107366

end - begin = 2000ms

暂停

  虽然suspend和resume方法可以分别使得线程暂停和回复,但是这两个方法因为有缺点而已经被弃用。

缺点:

  • 独占:在使用suspend和resume方法时,如果使用不当,极易造成公共的同步对象独占,使得其他线程无法访问公共同步对象。
  • 不同步:在使用suspend与resume方法时也容易因为线程而导致数据不同步的情况。

yield方法

  可以使用yield方法进行暂停。

  yield()方法的作用是放弃当前的CPU资源,将它让给其他任务去占用CPU执行时间。但放弃的时间不确定,有可能刚刚放弃,马上又获得CPU时间片。

  1. public class MyThread extends Thread {
  2. @Override
  3. public void run() {
  4. long beginTime = System.currentTimeMillis();
  5. int count = 0;
  6. for (int i = 0; i < 50000000; i++) {
  7. //Thread.yield();
  8. count = count + (i + 1);
  9. }
  10. long endTime = System.currentTimeMillis();
  11. System.out.println("用时: " + (endTime - beginTime) + "ms");
  12. }
  13. public static void main(String[] args) {
  14. MyThread myThread = new MyThread();
  15. myThread.start();
  16. }
  17. }

输出结果:

用时: 21ms

  去掉注释//Thread.yield()后。

输出结果:

用时: 4471ms

  从第二次输出可以看出,用时明显变长。

停止

  虽然stop()可以停止一个线程,但是这个方法是不安全的,而且是已经被弃用作废的,最好不要使用它。

interrupt()方法

  interrupt()方法的使用效果并不像for+break语句那个,马上就停止循环。调用interrupt()方法仅仅是在当前线程中打了一个停止的标记,并不是真正停止线程。

判断线程是否是停止状态

  • this.interrupted():测试当前线程是否已经是中断状态,执行后具有将状态标志清楚为false的功能,为static方法。
  • this.isInterrupted():测试线程Thread对象是否已经是中断状态,但是不清除状态标志。
  1. public class MyThread extends Thread {
  2. public static void main(String[] args) {
  3. Thread.currentThread().interrupt();
  4. System.out.println("是否停止1? " + Thread.interrupted());
  5. System.out.println("是否停止2? " + Thread.interrupted());
  6. System.out.println("end");
  7. }
  8. }

输出结果:

是否停止1? true

是否停止2? false

end

  1. public class MyThread extends Thread {
  2. @Override
  3. public void run() {
  4. for (int i = 0; i < 50000; i++) {
  5. System.out.println(i);
  6. }
  7. }
  8. public static void main(String[] args) {
  9. try {
  10. MyThread myThread = new MyThread();
  11. myThread.start();
  12. Thread.sleep(1000);
  13. myThread.interrupt();
  14. System.out.println("是否停止1? " + myThread.isInterrupted());
  15. System.out.println("是否停止2? " + myThread.isInterrupted());
  16. System.out.println("end");
  17. } catch (InterruptedException e) {
  18. e.printStackTrace();
  19. }
  20. }
  21. }

输出结果(末尾):

49997

49998

49999

是否停止1? false

是否停止2? false

end

能停止线程的方法

  在run中加一个判断,如果停止了,则break跳出循环体。

  1. public class MyThread extends Thread {
  2. @Override
  3. public void run() {
  4. for (int i = 0; i < 50000000; i++) {
  5. if (this.interrupted()) {
  6. System.out.println("已经是停止状态了,我要退出了");
  7. break;
  8. }
  9. System.out.println(i);
  10. }
  11. }
  12. public static void main(String[] args) {
  13. try {
  14. MyThread myThread = new MyThread();
  15. myThread.start();
  16. Thread.sleep(1000);
  17. myThread.interrupt();
  18. System.out.println("end");
  19. } catch (InterruptedException e) {
  20. e.printStackTrace();
  21. }
  22. }
  23. }

输出结果(末尾):

160560

160561

160562

160563

160564

end

已经是停止状态了,我要退出了

  上述代码虽然可以停止线程,但是如果for的后面还有语句,那么还是会继续执行。

  因此可以用下述方法来解决。

  1. public class MyThread extends Thread {
  2. @Override
  3. public void run() {
  4. try {
  5. for (int i = 0; i < 50000000; i++) {
  6. if (this.interrupted()) {
  7. System.out.println("已经是停止状态了,我要退出了");
  8. throw new InterruptedException();
  9. }
  10. System.out.println(i);
  11. }
  12. System.out.println("for结束");
  13. } catch (InterruptedException e) {
  14. System.out.println("进入run中的catch了");
  15. e.printStackTrace();
  16. }
  17. }
  18. public static void main(String[] args) {
  19. try {
  20. MyThread myThread = new MyThread();
  21. myThread.start();
  22. Thread.sleep(1000);
  23. myThread.interrupt();
  24. System.out.println("end");
  25. } catch (InterruptedException e) {
  26. e.printStackTrace();
  27. }
  28. }
  29. }

输出结果(末尾):

152891

152892

152893

152894

end

已经是停止状态了,我要退出了

进入run中的catch了

java.lang.InterruptedException

at mythread.MyThread.run(MyThread.java:13)

Java多线程程序休眠、暂停与停止的更多相关文章

  1. JAVA多线程程序ProgressBar2

    JAVA多线程程序ProgressBar2 题目简介: 思路分析:与上一篇:JAVA多线程程序ProgressBar类似,本篇避免过于冗杂,所以在此没有给出. 实验代码: import java.aw ...

  2. JAVA多线程程序ProgressBar

    JAVA多线程程序ProgressBar 题目简介: 思维导图: 实验代码:建议先看CalThread类,计算线程的实现,再作基本CalFrame类的界面, 然后作ReadThread类,结合CalF ...

  3. Java多线程-程序运行堆栈分析

    class文件内容 class文件包含JAVA程序执行的字节码:数据严格按照格式紧凑排列在class文件中的二进制流,中间无任何分隔符:文件开头有一个0xcafebabe(16进制)特殊的一个标志. ...

  4. java 多线程7(线程的停止)

    notify(): 是很温和的唤醒线程的方法,它不可以指定清除哪一个异常 interrupt(): 粗暴的方式,强制清除线程的等待状态,被清除的线程会接收到一个InterruptedException ...

  5. 简述Java多线程(一)

    JAVA多线程 程序:是指令和数据的有序集合,其本身没有任何运行的含义,是一个静态的概念. 进程:是执行程序的一次执行过程,是一个动态的概念,是系统资源分配的单位. 线程是CPU调度和执行的单位. 创 ...

  6. Java多线程(上)

    Java多线程 程序.进程和线程 一.程序 程序是存储在磁盘上, 包含可执行机器指令和数据的静态实体. 即进程或者任务是处于活动状态的计算机程序. 二.进程 进程是资源(CPU.内存等)分配的基本单位 ...

  7. java多线程系列六、线程池

    一. 线程池简介 1. 线程池的概念: 线程池就是首先创建一些线程,它们的集合称为线程池. 2. 使用线程池的好处 a) 降低资源的消耗.使用线程池不用频繁的创建线程和销毁线程 b) 提高响应速度,任 ...

  8. 【Java多线程】Executor框架的详解

    在Java中,使用线程来异步执行任务.Java线程的创建与销毁需要一定的开销,如果我们为每一个任务创建一个新线程来执行,这些线程的创建与销毁将消耗大量的计算资源.同时,为每一个任务创建一个新线程来执行 ...

  9. java多线程(五)之总结(转)

    引 如果对什么是线程.什么是进程仍存有疑惑,请先Google之,因为这两个概念不在本文的范围之内. 用多线程只有一个目的,那就是更好的利用cpu的资源,因为所有的多线程代码都可以用单线程来实现.说这个 ...

随机推荐

  1. [Unity Quaternion]四元数Quaternion的计算方式

    什么是Quaternion四元数 1843年,William Rowan Hamilton发明了四元数,但直到1985年才有一个叫Ken Shoemake的人将四元数引入计算机图形学处理领域.四元数在 ...

  2. fedora 挂载 小米手机 (估计其它android设备也是类似操作)

    1 参考ubuntu挂载 在Ubuntu挂载使用MTP设备步骤如下: 1.将MTP设备连接至PC机 2.如果是第一次使用MTP设备需要安装以下软件,否则可以跳过此步骤: $ sudo apt-get ...

  3. MYSQL 主从服务器配置工作原理

    一.        主从配置的原理: Mysql的 Replication 是一个异步的复制过程,从一个 Mysql instace(我们称之为 Master)复制到另一个 Mysql instanc ...

  4. STM32——timer

    原文地址: http://blog.sina.com.cn/s/blog_49cb42490100s6ud.html   1.     STM32的Timer简介 STM32中一共有11个定时器,其中 ...

  5. 查找 SqlServer死锁

    use master if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[sp_who_lock]') ) dr ...

  6. td文字过长部分显示,鼠标移动显示全部内容

    只要在该td中加上title属性,鼠标移到这里就会看到全部内容, 在td中加上div,属性设置如下,就能显示宽度为200px的内容,大于则隐藏.代码如下: <td title="我是代 ...

  7. Java程序员常犯的10个错误

      本文总结了Java程序员常犯的10个错误. #1. 把Array转化成ArrayList 把Array转化成ArrayList,程序员经常用以下方法: List<String> lis ...

  8. Ehcache jgroups方式同步缓存出现问题总结

    ehcache配置文件按官网配置如下: <?xml version="1.0" encoding="UTF-8"?> <ehcache> ...

  9. 高仿xx教育网

    2014年2月26日 16:24:50 好久没做 php了,考虑到老婆是教育行业,高仿一个教育辅导机构的网站 加油

  10. Tomcat用法--Servlet开发

    本来想玩一下微信公众号开发,没想到学习曲线真是恶心的很,首先你要配置Tomcat--你要会Servlet--你要会JSP,妈的!贴出来 快哭瞎了,各种文档,好吧,提供一个教你搞java EE文档的博客 ...