1、线程睡眠---sleep:
线程睡眠的原因:线程执行的太快,或需要强制执行到下一个线程。
线程睡眠的方法(两个):sleep(long millis)在指定的毫秒数内让正在执行的线程休眠。
sleep(long millis,int nanos)在指定的毫秒数加指定的纳秒数内让正在执行的线程休眠。
扩展:Java线程调度是Java多线程的核心,只有良好的调度,才能充分发挥系统的性能,提高程序的执行效率。但是不管程序员怎么编写调度,只能最大限度的影响线程执行的次序,而不能做到精准控制。因为使用sleep方法之后,线程是进入阻塞状态的,只有当睡眠的时间结束,才会重新进入到就绪状态,而就绪状态进入到运行状态,是由系统控制的,我们不可能精准的去干涉它,所以如果调用Thread.sleep(1000)使得线程睡眠1秒,可能结果会大于1秒。
整理:睡眠,就是让线程进入阻塞状态,时间到了,进入就绪状态,但由于无法控制就绪--->运行状态的时间,所以时间实际可能会大于睡眠时间。并且会抛出异常
//异常连接
2、线程让步---yield:
该方法和sleep方法类似,也是Thread类提供的一个静态方法,可以让正在执行的线程暂停,但是不会进入阻塞状态,而是直接进入就绪状态。相当于只是将当前线程暂停一下,然后重新进入就绪的线程池中,让线程调度器重新调度一次。也会出现某个线程调用yield方法后暂停,但之后调度器又将其调度出来重新进入到运行状态。
整理:让步,就是让线程从运行---->就绪状态,让线程重新调用下
sleep和yield的区别:
①、sleep方法声明抛出InterruptedException,调用该方法需要捕获该异常。yield没有声明异常,也无需捕获。
②、sleep方法暂停当前线程后,会进入阻塞状态,只有当睡眠时间到了,才会转入就绪状态。而yield方法调用后 ,是直接进入就绪状态。
3、线程合并---join:
当B线程执行到了A线程的.join()方法时,B线程就会等待,等A线程都执行完毕,B线程才会执行。
join可以用来临时加入线程执行。
整理:线程合并,就是让A线程把任务执行完,B线程才能开始执行
4、停止线程:
原stop方法因有缺陷已经停用了,那么现在改如何停止线程?现在分享一种,就是让run方法结束。
开启多线程运行,运行的代码通常是循环结构,
整理:利用run方法,设置条件,结束线程。但是有一种特殊情况:
线程处于冻结状态,标记就无法读取到。
特殊情况:当线程处于了冻结状态,就不会读取到标记,也就不会结束。当没有指定方法让冻结的线程回复到运行状态时,我们需要对冻结状态进行清除,也就是强制让线程恢复到运行状态中来,这样可就可以操作标记让线程结束。
Thread类提供该方法: interrupt();(如果线程在调用Object类的wait()、wait(long)、wait(long,int)方法,或者该类的join()、join(long)、join(long、int)、sleep(long)或sleep(long、int)方法过程中受阻,则其中断状态将被清除,还将收到一个InterruptedException。)
只要控制住循环,就可以让run方法结束,也就是线程结束。
5、设置优先级:
每个线程执行时都有一个优先级的属性,优先级高的线程可以获得较多的执行机会,而优先级低的线程则获得较少的执行机会。与线程休眠类似,线程的优先级仍然无法保障线程的执行次序。只不过,优先级高的线程获取CPU资源的概率较大,优先级低的也并非没机会执行。
整理:优先级只能保证获取CPU资料的概率比优先级低的线程大( setPriority(9))
常用的定义:
MAX_PRIORITY =10
MIN_PRIORITY =1
NORM_PRIORITY =5
package thread.basic;
import jdk.nashorn.internal.objects.annotations.Where;
/**
* @Package:thread.basic
* @Class:ThreadState
* @Description: TODO
* @Author:何仲奇
* @Date:Created in 2019-03-14 0:23
* @Company:
* @Version:
* @Modified By:
*/
public class ThreadState {
public static void main(String[] args) throws InterruptedException {
//new Thread(new RunnableDemo1(), "倒计时").start();
YieldDemo ms = new YieldDemo();
Thread t1 = new Thread(ms,"张三吃完还剩");
Thread t2 = new Thread(ms,"李四吃完还剩");
Thread t3 = new Thread(ms,"王五吃完还剩");
//t1.start();
//t2.start();
//t3.start();
/**
* 3、线程合并---join:
*
* 当B线程执行到了A线程的.join()方法时,B线程就会等待,等A线程都执行完毕,B线程才会执行。
*
* join可以用来临时加入线程执行。
*/
/* t1.start();
t1.join();
t2.start();
t3.start();*/
System.out.println( "主线程");
int num = 0;
StopTh st = new StopTh();
Thread t11 = new Thread(st);
Thread t22 = new Thread(st);
t11.start();
t22.start();
//设置主线程执行50次,执行结束之后停止线程
while (true) {
if(num++ == 50){
st.flagChange();
break;
}
System.out.println(Thread.currentThread().getName() + "..." + num);
}
//特殊情况:当线程处于了冻结状态,
//就不会读取到标记,也就不会结束。当没有指定方法让冻结的线程回复到运行状态时,
// 我们需要对冻结状态进行清除,也就是强制让线程恢复到运行状态中来,这样可就可以操作标记让线程结束。
//Thread类提供该方法: interrupt();
// (如果线程在调用Object类的wait()、wait(long)、wait(long,int)方法,
// 或者该类的join()、join(long)、join(long、int)、sleep(long)或sleep(long、int)方法过程中受阻,
// 则其中断状态将被清除,还将收到一个InterruptedException。)
/**
* 5、设置优先级:
*每个线程执行时都有一个优先级的属性,优先级高的线程可以获得较多的执行机会,
* 而优先级低的线程则获得较少的执行机会。与线程休眠类似,线程的优先级仍然无法保障线程的执行次序。
* 只不过,优先级高的线程获取CPU资源的概率较大,优先级低的也并非没机会执行。
*
* Thread类中提供了优先级的三个常量,代码如下:
*/
//MAX_PRIORITY =10
//MIN_PRIORITY =1
//NORM_PRIORITY =5
RunnableDemo1 td = new RunnableDemo1();
Thread t111 = new Thread(td,"张三");
//设置优先级
t111.setPriority(9);
t111.start();//设置完毕
}
}
/**
* 1、线程睡眠---sleep:
* <p>
* 线程睡眠的原因:线程执行的太快,或需要强制执行到下一个线程。
* <p>
* 线程睡眠的方法(两个):sleep(long millis)在指定的毫秒数内让正在执行的线程休眠。
* <p>
* sleep(long millis,int nanos)在指定的毫秒数加指定的纳秒数内让正在执行的线程休眠。
*/
/**
* 扩展:Java线程调度是Java多线程的核心,只有良好的调度,才能充分发挥系统的性能,
* 提高程序的执行效率。但是不管程序员怎么编写调度,只能最大限度的影响线程执行的次序,
* 而不能做到精准控制。因为使用sleep方法之后,线程是进入阻塞状态的,
* 只有当睡眠的时间结束,才会重新进入到就绪状态,而就绪状态进入到运行状态,
* 是由系统控制的,我们不可能精准的去干涉它,
* 所以如果调用Thread.sleep(1000)使得线程睡眠1秒,可能结果会大于1秒。
*/
class RunnableDemo1 implements Runnable {
int time = 10;
@Override
public void run() {
while (true) {
if(time >= 0) {
System.out.println(Thread.currentThread().getName() + ":" +time--);
}
try {
//睡眠时间为1秒
Thread.sleep(1000);
//这里涉及关于异常问题
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/**
* 2、线程让步---yield:
*该方法和sleep方法类似,也是Thread类提供的一个静态方法,
* 可以让正在执行的线程暂停,但是不会进入阻塞状态,而是直接进入就绪状态。
* 相当于只是将当前线程暂停一下,然后重新进入就绪的线程池中,
* 让线程调度器重新调度一次。也会出现某个线程调用yield方法后暂停,
* 但之后调度器又将其调度出来重新进入到运行状态。
*/
class YieldDemo implements Runnable{
int count = 20;
@Override
public void run() {
while (true) {
if(count>0){
System.out.println(Thread.currentThread().getName() + count-- + "个瓜");
if(count % 2 == 0){
//线程让步
Thread.yield();
}
}
}
}
}
/**
* sleep和yield的区别:
*
* ①、sleep方法声明抛出InterruptedException,调用该方法需要捕获该异常。yield没有声明异常,也无需捕获。
*
* ②、sleep方法暂停当前线程后,会进入阻塞状态,只有当睡眠时间到了,才会转入就绪状态。
* 而yield方法调用后 ,是直接进入就绪状态。
*/
/**
* 4、停止线程:
*
* 原stop方法因有缺陷已经停用了,那么现在改如何停止线程?现在分享一种,就是让run方法结束。
*
* 开启多线程运行,运行的代码通常是循环结构,只要控制住循环,就可以让run方法结束,也就是线程结束。
*/
class StopTh implements Runnable{
private boolean flag = true;
@Override
public void run() {
while(flag){
System.out.println(Thread.currentThread().getName() + "stop run" );
}
}
public void flagChange(){
flag = false;
}
}