一、线程生命周期

线程被创建启动以后,他既不是一启动就进入执行状态,也不是一直处于执行状态,在线程的生命周期中,它要经过新建(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. 如何使用Nsight System?

    如何使用Nsight System?

  2. TcaplusDB祝大家端午安康!

    "五月五,端午到,赛龙舟,真热闹.吃粽子,带香包,蚊虫不来身边闹."这首脍炙人口.描绘着端午节风俗的儿歌,想必大家都听过. 每年的农历五月初五,是我国四大传统节日(春节.清明节.端 ...

  3. python-selenium 引入包或者类的清晰写法

    #cording=gbk#一般最上面放系统自带的包或者类import os import time##第二层放第三方下载的包或者类from selenium import webdriverfrom ...

  4. MySQL笔记01(黑马)

    一.数据库基本介绍 目标:了解数据库的功能和常见数据库分类.数据库产品 数据库基本知识 数据库分类 SQL简介 MySQL访问 1.数据库基本知识 目标:了解数据库的概念和数据库的作用 概念 数据库: ...

  5. P4779 【模板】单源最短路径(标准版)单源最短路Dijkstra

    题目描述 给定一个$n$个点,$m$条有向边的带非负权图,请你计算从$s$出发,到每个点的距离. 数据保证你能从$s$出发到任意点. 输入格式 第一行为三个正整数$n,m,s$. 第二行起$m$行,每 ...

  6. 用Java如何设计一个阻塞队列,然后说说ArrayBlockingQueue和LinkedBlockingQueue

    前言 用Java如何设计一个阻塞队列,这个问题是在面滴滴的时候被问到的.当时确实没回答好,只是说了用个List,然后消费者再用个死循环一直去监控list的是否有值,有值的话就处理List里面的内容.回 ...

  7. 【NX二次开发】多种变换

    变换的种类: uf5942 矩阵乘积变换 uf5943 平移变换 uf5944 缩放变换 uf5945 旋转变换 uf5946 镜像变换 最后使用 uf5947 实现uf5942-uf5946的变换. ...

  8. 懒人 IDEA 插件推荐:EasyCode 一键帮你生成所需代码

    Easycode是idea的一个插件,可以直接对数据的表生成entity,controller,service,dao,mapper,无需任何编码,简单而强大. 1.安装(EasyCode) 我这里的 ...

  9. Mysql优化(出自官方文档) - 第四篇

    Mysql优化(出自官方文档) - 第四篇 目录 Mysql优化(出自官方文档) - 第四篇 1 Condition Filtering 2 Constant-Folding Optimization ...

  10. Room-数据持久化存储(入门)

    @ 目录 一.简单使用 1.Entity 2.Dao 3.DataBase 4.使用 二.参数解析 1.Entity 2.Dao 3.查询方式 总结 # 前言 官方简介: Room 持久性库在 SQL ...