Java多线程之线程的控制



  • 线程中的7 种非常重要的状态: 

初始New、可运行Runnable、运行Running、阻塞Blocked、锁池lock_pool、等待队列wait_pool、结束Dead

如果将“锁池”和“等待队列”都看成是“阻塞”状态的特殊情况,那么可以将线程归纳为5个状态:

新建,就绪,运行,阻塞,死亡。

                                        

                 ┌--------------------< 阻塞

                 ↓                    (1)(2)(3)        结束

                ①②③        OS调度         ↑             ↑

    初始-------> 可运行 ↹---------------↹ 运行 >-----------┤

    t.start()启动 ↑                        ↓              ↓o.wait()

                 └-----< 锁池 ←---------<┘←-------< 等待队列

                  获得锁标志   synchronized(o)

注意:图中标记依次为

    ①输入完毕;    ②wake up    ③t1 退出

    ⑴等待输入(输入设备进行处理,而CUP 不处理),则放入阻塞,直到输入完毕。

    ⑵线程休眠sleep()

    ⑶t1.join()将t1 加入运行队列,直到t1 退出,当前线程才继续。

        特别注意:①②③与⑴⑵⑶是一一对应的。

    进程的休眠:Thread.sleep(1000);//括号中以毫秒为单位

    当线程运行完毕,即使在结束时时间片还没有用完,CPU 也放弃此时间片,继续运行其他程序。

    T1.join 实际上是把并发的线程编成并行运行。







  •    实现对多线程的控制:

控制多线程,记住下面几个API就够了:

   1,start方法:创建一个线程。值得注意的是,new一个线程的时候,只是表示该线程处于新建状态,并不是执行状态。使用start方法后启动一个线程,线程处于就绪状态,也并不是说直接就在运行了,它表示这个线程可以运行了,但是什么时候开始运行,取决于JVM里线程调度器的调度。

   2,stop方法:结束一个线程。容易导致死锁,不推荐使用。值得注意的是,不要试图在一个线程已死亡的情况下再次调用start方法来启动该线程,会报illegalThreadStateException错的。

   3,join方法:在一个线程中加入一个线程。当在某个程序执行流中调用了其他线程的join方法时,调用线程将被阻塞,直到被join方法加入的join线程完成为止。

   4,sleep方法:让线程睡觉。使当前正在执行的线程暂停一段时间,并进入阻塞状态。

   5,yield方法:和sleep方法相似,让当前正在执行的线程暂停一下,但是他不会阻塞这个线程,它只是将这个线程转入就绪状态。

   6,setPriority方法:设置线程优先级。set和getPriority设置和获得线程的优先级,1到10一共10个数字,默认是5,数字越大优先级越高,越容易获得执行机会。 为了跨平台,最好不要使用优先级决定线程的执行顺序。这个时候使用3个静态常量:max_Priority,min_Priority,norm_Priority。

   7,setDaemon方法:设置后台线程。   Daemon Threads(daemon 线程)是服务线程,当其他线程全部结束,只剩下daemon线程时,虚拟机会立即退出。

    Thread t = new DaemonThread();

    t.setDaemon(true);//setDaemon(true)把线程标志为daemon,其他的都跟一般线程一样

    t.start();//一定要先setDaemon(true),再启动线程

    在daemon线程内启动的线程,都定为daemon线程

    8,wait(),Notify()方法在后面介绍同步锁的时候在仔细说。 在运行状态中,线程调用wait(),表示这线程将释放自己所有的锁标记,同时进入这个对象的等待队列。等待队列的状态也是阻塞状态,只不过线程释放自己的锁标记。用notify()方法叫出之后,紧跟着刚才wait();的位置往下执行。如果一个线程调用对象的notify(),就是通知对象等待队列的一个线程出列。进入锁池。如果使用notifyall()则通知等待队列中所有的线程出列。

  • 有一个问题,在什么情况下,一个线程将进入阻塞状态?

1,线程调用了sleep方法,主动放弃它所占有的处理器资源

2,线程调用了阻塞式IO方法,在方法返回之前,线程阻塞了

3,线程试图获得一个同步监听器,但是该同步监视器正被其他的线程持有

4,线程在等待某一个notify通知

5,线程调用了suspend方法将线程挂起了。





要是让一个线程由阻塞状态变成了就绪状态正好和上面的情况相反,最后一点使用resume方法就好了。值得注意的是:suspend()将运行状态推到阻塞状态(注意不释放锁标记)。恢复状态用resume()。Stop()释放全部。这几个方法上都有Deprecated 标志,说明这个方法不推荐使用。一般来说,主方法main()结束的时候线程结束,可是也可能出现需要中断线程的情况。对于多线程一般每个线程都是一个循环,如果中断线程我们必须想办法使其退出。如果想结束阻塞中的线程(如sleep 或wait),可以由其他线程对其对象调用interrupt()。用于对阻塞(或锁池)会抛出例外Interrupted。

Java多线程之线程的控制的更多相关文章

  1. Java多线程之线程的通信

    Java多线程之线程的通信 在总结多线程通信前先介绍一个概念:锁池.线程因为未拿到锁标记而发生的阻塞不同于前面五个基本状态中的阻塞,称为锁池.每个对象都有自己的锁池的空间,用于放置等待运行的线程.这些 ...

  2. java多线程与线程间通信

    转自(http://blog.csdn.net/jerrying0203/article/details/45563947) 本文学习并总结java多线程与线程间通信的原理和方法,内容涉及java线程 ...

  3. Java多线程之线程协作

    Java多线程之线程协作 一.前言 上一节提到,如果有一个线程正在运行synchronized 方法,那么其他线程就无法再运行这个方法了.这就是简单的互斥处理. 假如我们现在想执行更加精确的控制,而不 ...

  4. Java多线程之线程的暂停

    Java多线程之线程的暂停 下面该稍微休息一下了呢……不过,这里说的是线程休息,不是我们哦.本节将介绍一下让线程暂停运行的方法. 线程Thread 类中的sleep 方法能够暂停线程运行,Sleep ...

  5. Java 多线程:线程池

    Java 多线程:线程池 作者:Grey 原文地址: 博客园:Java 多线程:线程池 CSDN:Java 多线程:线程池 工作原理 线程池内部是通过队列结合线程实现的,当我们利用线程池执行任务时: ...

  6. Java多线程之线程其他类

    Java多线程之线程其他类 实际编码中除了前面讲到的常用的类之外,还有几个其他类也有可能用得到,这里来统一整理一下: 1,Callable接口和Future接口 JDK1.5以后提供了上面这2个接口, ...

  7. Java多线程之线程的同步

    Java多线程之线程的同步 实际开发中我们也经常提到说线程安全问题,那么什么是线程安全问题呢? 线程不安全就是说在多线程编程中出现了错误情况,由于系统的线程调度具有一定的随机性,当使用多个线程来访问同 ...

  8. Java多线程父子线程关系 多线程中篇(六)

    有的时候对于Java多线程,我们会听到“父线程.子线程”的概念. 严格的说,Java中不存在实质上的父子关系 没有方法可以获取一个线程的父线程,也没有方法可以获取一个线程所有的子线程 子线程的消亡与父 ...

  9. 关于Java多线程的线程同步和线程通信的一些小问题(顺便分享几篇高质量的博文)

    Java多线程的线程同步和线程通信的一些小问题(顺便分享几篇质量高的博文) 前言:在学习多线程时,遇到了一些问题,这里我将这些问题都分享出来,同时也分享了几篇其他博客主的博客,并且将我个人的理解也分享 ...

随机推荐

  1. python之tuple

    1.python元组 Python的元组与列表类似,不同之处在于元组的元素不能修改. 元组使用小括号,列表使用方括号. #创建元组 >>> tuple2 = 123,456,'hel ...

  2. 前端工程化webpack(一)

    webpack 的基本用法   1.app.js 引入模块 import moduleLog from './module.js' //引入moduleLog从./module.js 2.module ...

  3. 如何实现VM框架中的数据绑定

    作者:佳杰 本文原创,转载请注明作者及出处 如何实现VM框架中的数据绑定 一:数据绑定概述 视图(view)和数据(model)之间的绑定 二:数据绑定目的 不用手动调用方法渲染视图,提高开发效率:统 ...

  4. [转]-nohup-真正的Shell后台运行

    &方式: Unix/Linux下一般想让某个程序在后台运行,很多都是使用 & 在程序结尾来让程序自动运行. 比如我们要运行mysql在后台: /usr/local/mysql/bin/ ...

  5. VFS四大对象之四-struct file

    继上一篇文章: http://www.cnblogs.com/linhaostudy/p/7428971.html 四.file结构体 文件对象:注意文件对象描述的是进程已经打开的文件.因为一个文件可 ...

  6. mysql 在B数据库下 创建一个与A数据库中一样的表

    1.创建数据内容与结构一致(不会复制索引以及外键) create table B.test as select * from A.test; 2.把上面的步骤分开,先复制结构 create table ...

  7. hbmy周赛1--A

    Age Sort You are given the ages (in years) of all people of a country with at least 1 year of age. Y ...

  8. LuceneNet 实现快速大文件大数据查询

    做过站内搜索的朋友应该对Lucene.Net不陌生,因为用普通的sql  like查询肯定是不行的,太慢了. 首先说明的是--Lucene.Net只是一个全文检索开发包,不是一个成型的搜索引擎, 它的 ...

  9. angular1项目打包app及logo和启动图片的设置

    打包思想:ionic和angular混合开发app,那么纯angular1的项目也是可以打包出来. 技术需要:安装一个新的ionic2的项目,环境配置成功,这里打包的配置需要 http://www.c ...

  10. i++是否原子操作?并解释为什么?

    都不是原子操作.理由: 1.i++分为三个阶段: 内存到寄存器寄存器自增写回内存这三个阶段中间都可以被中断分离开.  2.++i首先要看编译器是怎么编译的, 某些编译器比如VC在非优化版本中会编译为以 ...