一、线程生命周期

线程被创建启动以后,他既不是一启动就进入执行状态,也不是一直处于执行状态,在线程的生命周期中,它要经过新建(New)、就绪(Runnable)、运行(Running)、阻塞(Blocked)和死亡(Dead)五种状态

1、新建状态

当程序使用new关键字创建了一个线程后,该线程就处于新建状态

2、就绪状态

当线程对象调用了start()方法之后,该线程就处于就绪状态,java虚拟机会为其创建方法调用栈和程序计数器。

这个状态中的线程并没有开始执行线程,只是表示该线程可以运行了,至于何时运行,取决于JVM线程调度器调度。

3、运行状态

如果处于就绪状态的线程获得了CPU,开始执行run()方法的线程执行体,则该线程处于运行状态。

4、阻塞状态

当运行状态的线程发生如下情况时,线程会进入阻塞状态:

(1)线程调用sleep()方法主动放弃所占用的处理器资源。

(2)线程调用了一个阻塞式IO方法,在该方法返回之前,该线程被阻塞

(3)线程试图获得一个同步监视器,但该同步监视器正被其他线程所持有。

(4)线程在等待某个通知(notify)

(5)程序调用了线程的suspend()方法将线程挂起,这个方法在jdk1.6中已经过时,它容易导致死锁,不建议使用。

针对上面阻塞状态,当发生下面特定情况可以解除阻塞状态:

(1)sleep()方法经过了指定时间。

(2)阻塞式IO方法已经返回

(3)线程成功获得了一个同步监视器。

(4)线程在等待某个通知时,其他线程发出了一个通知

(5)处于挂起的线程被调用了resume()恢复方法

5、线程死亡

线程结束后就处于死亡状态,有三种结束方式:

(1)run()或call()方法执行完成,线程正常结束

(2)线程抛出一个未捕获的Exception或者Error

(3)直接调用线程的stop()方法结束线程——容易死锁,不建议使用

isAlive()方法可以判断线程是否死亡,当处于就绪、运行、阻塞状态时返回true,处于新建、死亡状态时返回false。

已经死亡的线程不能重新启动,否则引发IllegalThreadStateException。

二、控制线程

java线程提供了一些简便的工具方法,利用这些方法可以很好的控制线程

1、join()

join()方法:让一个线程等待一个线程完成。

package threadtest;
public class ThreadTest implements Runnable {
@Override
public void run() {
for(int i=0;i<30;i++) {
System.out.println(Thread.currentThread().getName() + " " + i);
} } public static void main(String[] args) throws InterruptedException { ThreadTest target1 = new ThreadTest();
Thread t1 = new Thread(target1,"t1");
t1.start();
for(int i=0;i<30;i++) {
System.out.println(Thread.currentThread().getName() + " " + i);
//开始主线程和t1线程并发执行,当main线程的i到15时,调用了t1线程的join方法,
//此时主线程等待t1线程,直到t1结束时才跑main,
//join后,主线程处于阻塞状态
if(i == 15) {
t1.join();
}
}
} }

2、线程睡眠 sleep()

如果需要让当前线程暂停一段时间,则可以使用sleep()方法

package threadtest;

import java.time.LocalTime;

public class ThreadTest implements Runnable {

    @Override
public void run() {
for(int i=0;i<30;i++) {
System.out.println(Thread.currentThread().getName() + " " + i +" "+ LocalTime.now());
if(i == 15){
try {
Thread.sleep(10000);//10s
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} public static void main(String[] args) throws InterruptedException { ThreadTest target1 = new ThreadTest();
Thread t1 = new Thread(target1,"t1");
t1.start();
}
}

3、线程让步 yield()

yield()方法会让线程直接进入就绪状态,主要作用就是让当前线程暂停一下。完全有可能线程yield()后,线程调度器又将该线程调度出来执行。

yield()暂停后,只有优先级与当前线程相同或者优先级比当前线程更高的处于就绪状态的线程才有机会获得执行机会。

package threadtest;

import java.time.LocalTime;

public class ThreadTest implements Runnable {
@Override
public void run() {
for(int i=0;i<30;i++) {
System.out.println(Thread.currentThread().getName() + " " + i +" "+ LocalTime.now());
if(i == 15){
Thread.yield();//线程让步
}
}
} public static void main(String[] args) throws InterruptedException { ThreadTest target1 = new ThreadTest();
Thread t1 = new Thread(target1,"t1");
t1.start();
for(int i=0;i<10;i++) {
System.out.println(Thread.currentThread().getName() + " " + i +" "+ LocalTime.now());
}
}
}

sleep()和yield()方法的区别

(1)sleep暂停后会给其他线程机会,不会理会其他线程的优先级,但yield只给优先级相同或者更高的线程机会

(2)sleep将线程转为阻塞状态,yield将线程转为就绪状态

(3)sleep方法声明抛出了InterruptedException异常,所以用sleep要么捕捉该异常,要么抛出该异常。

(4)sleep比yield有更好的移植性,通常不建议使用yield方法来控制并发线程的执行

线程的优先级

每个线程执行时都有一定的优先级,优先级高的线程能获得更多的执行机会。每个线程的默认优先级与创建它的父线程优先级相同。默认情况下,main线程具有普通优先级

Thread类中 setPriority(int newPriority)和getPriority()方法分别设置和获取线程的优先级。

setPriority(int newPriority)的参数是一个整数,范围1-10;也可以是三个静态常量

MAX_PRIORITY:10

MIN_PRIORITY:1

NORM_PRIORITY:5

package threadtest;

import java.time.LocalTime;

public class ThreadTest implements Runnable {
@Override
public void run() {
for(int i=0;i<30;i++) {
System.out.println(Thread.currentThread().getName() + " " + i +" "+ LocalTime.now());
if(i == 15){
Thread.yield();
}
}
} public static void main(String[] args) throws InterruptedException { ThreadTest target1 = new ThreadTest();
Thread t1 = new Thread(target1,"t1");
Thread t2 = new Thread(target1,"t2");
t2.setPriority(Thread.MAX_PRIORITY);//设置优先级
t1.start();
t2.start();
}
}

java并发编程基础—生命周期与线程控制的更多相关文章

  1. Java并发1——线程创建、启动、生命周期与线程控制

    内容提要: 线程与进程 为什么要使用多线程/进程?线程与进程的区别?线程对比进程的优势?Java中有多进程吗? 线程的创建与启动 线程的创建有哪几种方式?它们之间有什么区别? 线程的生命周期与线程控制 ...

  2. Java并发编程基础

    Java并发编程基础 1. 并发 1.1. 什么是并发? 并发是一种能并行运行多个程序或并行运行一个程序中多个部分的能力.如果程序中一个耗时的任务能以异步或并行的方式运行,那么整个程序的吞吐量和可交互 ...

  3. 并发-Java并发编程基础

    Java并发编程基础 并发 在计算机科学中,并发是指将一个程序,算法划分为若干个逻辑组成部分,这些部分可以以任何顺序进行执行,但与最终顺序执行的结果一致.并发可以在多核操作系统上显著的提高程序运行速度 ...

  4. Java并发编程(您不知道的线程池操作), 最受欢迎的 8 位 Java 大师,Java并发包中的同步队列SynchronousQueue实现原理

    Java_并发编程培训 java并发程序设计教程 JUC Exchanger 一.概述 Exchanger 可以在对中对元素进行配对和交换的线程的同步点.每个线程将条目上的某个方法呈现给 exchan ...

  5. Java并发编程--基础进阶高级(完结)

    Java并发编程--基础进阶高级完整笔记. 这都不知道是第几次刷狂神的JUC并发编程了,从第一次的迷茫到现在比较清晰,算是个大进步了,之前JUC笔记不见了,重新做一套笔记. 参考链接:https:// ...

  6. Java并发编程(您不知道的线程池操作)

    Java并发编程(您不知道的线程池操作) 这几篇博客,一直在谈线程,设想一下这个场景,如果并发的线程很多,然而每个线程如果执行的时间很多的话,这样的话,就会大量的降低系统的效率.这时候就可以采用线程池 ...

  7. 【Java并发编程】之二:线程中断

    [Java并发编程]之二:线程中断 使用interrupt()中断线程 ​ 当一个线程运行时,另一个线程可以调用对应的Thread对象的interrupt()方法来中断它,该方法只是在目标线程中设置一 ...

  8. java并发编程笔记(七)——线程池

    java并发编程笔记(七)--线程池 new Thread弊端 每次new Thread新建对象,性能差 线程缺乏统一管理,可能无限制的新建线程,相互竞争,有可能占用过多系统资源导致死机或者OOM 缺 ...

  9. java并发编程笔记(五)——线程安全策略

    java并发编程笔记(五)--线程安全策略 不可变得对象 不可变对象需要满足的条件 对象创建以后其状态就不能修改 对象所有的域都是final类型 对象是正确创建的(在对象创建期间,this引用没有逸出 ...

随机推荐

  1. 腾讯 angel 3.0:高效处理模型

    腾讯 angel 3.0:高效处理模型 紧跟华为宣布新的 AI 框架开源的消息,腾讯又带来了全新的全栈机器学习平台 angel3.0.新版本功能特性覆盖了机器学习的各个阶段,包括:特征工程.模型训练. ...

  2. 向量算子优化Vector Operation Optimization

    向量算子优化Vector Operation Optimization 查看MATLAB命令View MATLAB Command 示例显示Simulink编码器 ,将生成向量的块输出,设置为标量,优 ...

  3. ITS智能交通监控系统技术解析

    ITS智能交通监控系统技术解析 红灯,逆行,变 车辆抓拍和车速检测 非法停车和交通流量检测 交叉路口违法检测 发生碰撞的交叉口是智能交通管理. 机动执法 当你需要一个可以移动的系统时,会跟着你移动.移 ...

  4. NVIDIA GPUs上深度学习推荐模型的优化

    NVIDIA GPUs上深度学习推荐模型的优化 Optimizing the Deep Learning Recommendation Model on NVIDIA GPUs 推荐系统帮助人在成倍增 ...

  5. JUC 并发编程--11, AQS源码原理解析, ReentrantLock 源码解读

    这里引用别人博客,不重复造轮子 https://blog.csdn.net/u012881584/article/details/105886486 https://www.cnblogs.com/w ...

  6. 5, java数据结构和算法: 栈 , 入栈, 出栈, 正序遍历,,逆序遍历

    直接上代码: class ArrayStack{ //用数组模拟栈 int maxSize; int[] stack; int top = -1;//表示栈顶 public ArrayStack(in ...

  7. 二、Linux基本防护措施

    修改账户有效期 chage命令的语法格式: chage –l    账户名称                                //查看账户信息 chage –E 时间 账户名称      ...

  8. (3)虚拟Web主机

    虚拟Web主机 作用:让一台Web服务器,提供多个页面 搭建方式: 1.基于域名的虚拟Web 2.基于端口的虚拟Web 3.基于IP地址的虚拟Web ######################### ...

  9. Java显式锁

    Java 显式锁. 一.显式锁 什么是显式锁? 由自己手动获取锁,然后手动释放的锁. 有了 synchronized(内置锁) 为什么还要 Lock(显示锁)? 使用 synchronized 关键字 ...

  10. Mybatis 中经典的 9 种设计模式!面试可以吹牛了

    虽然我们都知道有23个设计模式,但是大多停留在概念层面,真实开发中很少遇到.Mybatis源码中使用了大量的设计模式,阅读源码并观察设计模式在其中的应用,能够更深入的理解设计模式. Mybatis至少 ...