线程状态

JAVA定义了6种线程状态:

Thread.State
public enum State {
NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED;
}

分别是:

  • 新建状态·NEW
  • 运行状态·RUNNABLE
  • 阻塞状态·BLOCKED
  • 无限等待状态·WAITING
  • 休眠状态·TIMED_WAITING
  • 死亡状态·TERMINATED

线程不可能一直运行,除非瞬间执行结束。

为了给其他线程执行的机会,正在执行的线程会被中断。线程调度的细节取决于操作系统:

|--现代桌面操作系统和服务器操作系统采用抢占式调度策略,给每个线程一个时间段,时间到了就换其他线程执行,在选择下一线程时会考虑优先级。

|--手机等小型设备可能采用协作式调度策略,需要线程主动放弃占用的资源。


sleep

【运行】→sleep()→【休眠】

public class TestSleep {
public static void main(String[] args) {
// 获得当前运行的线程
Thread tMain = Thread.currentThread();
System.out.println("当前运行的线程是:" + tMain.toString());
for (int i = 0; i < 5; i++) {
System.out.println(i);
try {
// 使当前线程休眠1秒
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("END");
}
}

示例:显示时间

一个时间每秒更新,一个时间三秒更新(使用到了GUI)

这个示例用到了JAVA的图形界面编程,必须要继承JLabel类,因此无法继承Thread类,这也体现了Runnable接口的优点。

import java.awt.*;
import java.util.*;
import javax.swing.*;
public class 每秒更新 {
public static void main(String[] args) {
JFrame form1 = new JFrame();
form1.setBounds(300, 300, 350, 100);
form1.setVisible(true);
Container cp = form1.getContentPane();
cp.setLayout(new GridLayout(2, 1));
cp.add(new ShowDateLabel(1000));
cp.add(new ShowDateLabel(3000));
}
}
class ShowDateLabel extends JLabel implements Runnable {
private int sleepTime; // 休眠时间
public ShowDateLabel(int sleepTime) {
this.sleepTime = sleepTime;
// 启动线程
new Thread(this).start();
}
public void run() {
try {
while (true) {
// 显示当前时间
this.setText(new Date().toString());
Thread.sleep(sleepTime);
}
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
}

interrupt

中断线程,属于异常,尽量不用

import java.util.Date;
public class SleepInterrupt {
public static void main(String[] args) {
SleepThread thread = new SleepThread();
thread.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
thread.interrupt();
}
}
class SleepThread extends Thread {
boolean flag = true;
public void run() {
while (flag) {
System.out.println("===" + new Date() + "===");
try {
sleep(10000);
} catch (InterruptedException e) {
System.out.println("===Sleep被吵醒===");
return;
}
}
}
}

yield(礼不下庶人)

yield:屈服,退让

暂停当前正在执行的线程对象,并执行其他线程。

有机会被执行的是优先级相同或更高的线程,被yield的线程有可能被重新执行。

public class TestYield {
public static void main(String[] args) {
ThreadTestYield t1 = new ThreadTestYield("t1");
ThreadTestYield t2 = new ThreadTestYield(" t2");
// 如果t2优先级较低:yield时t1不让t2;sleep(100)时会让
// t2.setPriority(Thread.MAX_PRIORITY);
t1.start();
t2.start();
}
}
class ThreadTestYield extends Thread {
ThreadTestYield(String s) {
super(s);
}
public void run() {
for (int i = 1; i <= 100; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (i % 10 == 0) {
System.out.println(getName() + ": " + i + ": yield");
yield();
} else {
System.out.println(getName() + ": " + i);
}
}
}
}

join(等你做完)

join方法用于“等待线程终止”。

package ahjava.p06thread;
public class _31TestJoin {
public static void main(String[] args) {
MyThread2 t1 = new MyThread2("abcde");
t1.start();
try {
t1.join();// 等子线程先运行
} catch (InterruptedException e) {
}
for (int i = 1; i <= 10; i++) {
System.out.println("i am main thread");
}
}
}
class MyThread2 extends Thread {
MyThread2(String s) {
super(s);
}
public void run() {
for (int i = 1; i <= 5; i++) {
System.out.println("i am " + getName());
try {
sleep(1000);
} catch (InterruptedException e) {
return;
}
}
}
}

后台线程

线程分为前台线程、后台线程。

前台线程也叫用户线程

后台线程也叫守护线程

JVM的垃圾回收线程就是后台线程。

通过设置thread.setDaemon(true)可以把线程设为后台线程。但是需要在线程启动之前设置。

deamon本是守护神的意思。

前台线程在主线程结束后也要执行完才结束;

后台线程会在前台线程都结束之后自动结束,不会等自己执行完毕。

默认情况下,由前台线程创建的线程仍是前台线程,由后台线程创建的线程仍是后台线程。

public class TestDaemonThread extends Thread {
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.println(getName() + " " + i);
}
System.out.println("-----子线程结束-----");
}
public static void main(String[] args) {
TestDaemonThread t = new TestDaemonThread();
// 设为后台线程,不会看到“子线程结束”语句的输出
t.setDaemon(true);
t.start();
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + " " + i);
}
System.out.println("=====main线程结束=====");
}
}

Java基础教程——线程状态的更多相关文章

  1. Java基础教程——线程池

    启动新线程,需要和操作系统进行交互,成本比较高. 使用线程池可以提高性能-- 线程池会提前创建大量的空闲线程,随时待命执行线程任务.在执行完了一个任务之后,线程会回到空闲状态,等待执行下一个任务.(这 ...

  2. Java基础教程——线程局部变量

    线程局部变量 ThreadLocal,线程局部变量,不提供锁,不做线程共享,而是为每个线程提供变量的独立副本. import java.util.concurrent.*; public class ...

  3. Java基础教程——线程同步

    线程同步 synchronized:同步的 例:取钱 不做线程同步的场合,假设骗子和户主同时取钱,可能出现这种情况: [骗子]取款2000:账户余额1000 [户主]取款2000:账户余额1000 结 ...

  4. Java基础教程——线程通信

    线程通信:等待.唤醒 Object方法 这些方法在拥有资源时才能调用 notify 唤醒某个线程.唤醒后不是立马执行,而是等CPU分配 wait 等待,释放锁,不占用CPU资源 notifyAll 唤 ...

  5. Java基础教程:多线程基础(2)——线程间的通信

    Java基础教程:多线程基础(2)——线程间的通信 使线程间进行通信后,系统之间的交互性会更强大,在大大提高CPU利用率的同时还会使程序员对各线程任务在处理的过程中进行有效的把控与监督. 线程间的通信 ...

  6. Java基础教程:多线程基础——线程池

    Java基础教程:多线程基础——线程池 线程池 在正常负载的情况瞎,通过为每一个请求创建一个新的线程来提供服务,从而实现更高的响应性. new Thread(runnable).start() 在生产 ...

  7. Java基础教程:多线程基础(1)——基础操作

    Java:多线程基础(1) 实现多线程的两种方式 1.继承Thread类 public class myThread extends Thread { /** * 继承Thread类,重写RUN方法. ...

  8. Java基础教程:多线程基础(4)——Lock的使用

    Java基础教程:多线程基础(4)——Lock的使用 快速开始 Java 5中Lock对象的也能实现同步的效果,而且在使用上更加方便. 本节重点的2个知识点是:ReentrantLock类的使用和Re ...

  9. [译]线程生命周期-理解Java中的线程状态

    线程生命周期-理解Java中的线程状态 在多线程编程环境下,理解线程生命周期和线程状态非常重要. 在上一篇教程中,我们已经学习了如何创建java线程:实现Runnable接口或者成为Thread的子类 ...

随机推荐

  1. oracle ql/sql 相关语法解析

    这篇文章主要介绍了Oracle中游标Cursor基本用法详解,还是比较全面的,具有一定参考价值,需要的朋友可以了解下.   查询 SELECT语句用于从数据库中查询数据,当在PL/SQL中使用SELE ...

  2. ThreadLocal内存泄漏需要注意的

    前段时间在网上看到了一篇关于ThreadLocal内存泄漏的文章 于是个人也研究了下ThreadLocal 对象,其原理是: ThreadLocal 定义的变量值 会存储在当前线程的一个map集合中 ...

  3. Luogu P2179 [NOI2012]骑行川藏

    题意 给定 \(n\) 个路段,每个路段用三个实数 \(s_i,k_i,v^\prime_i\) 描述,最小化 \[F(v_1,\cdots v_n)=\sum\limits_{i=1}^{n}\fr ...

  4. Go语言的互斥锁Mutex

    目录 一.使用方法 二.死锁场景 1.Lock/Unlock不是成对出现 2.锁被拷贝使用 3.循环等待 一.使用方法 Mutext是互斥锁的意思,也叫排他锁,同一时刻一段代码只能被一个线程运行,两个 ...

  5. error: invalid command ‘bdist_wheel‘

    解决方法: pip3 install wheel 了解更多,请关注公众号

  6. How to: Debug X++ Code Running in .NET Business Connector [AX 2012]

    This topic has not yet been rated - Rate this topic  http://msdn.microsoft.com/EN-US/library/bb19006 ...

  7. Vue3教程:一个基于 Vue 3 + Vant 3 的商城项目开源啦!

    之前发布过一篇文章,告诉大家我要开发一个 Vue3 的商城项目并开源到 GitHub 上,供大家练手和学习,随后也一直有收到留言和反馈,问我开发到哪里了,什么时候开源之类的问题,今天终于可以通知大家, ...

  8. .NET 5 中的隐藏特性

    前言 双十一当天 .NET 5 正式发布带来了很多的新特性和改进,个人觉得非常香,并且花了 10 分钟时间就把自己的 4 个 .NET Core 3.1 的项目升级到了 .NET 5,堪称无痛. 但是 ...

  9. C++常见的面试题目整理

    本文列出C++面试中经常遇到的一些问题,都是一些常见的面试考点,如果后续遇到其他常见面试问题还会再次更新.希望对近期参加面试的同学有一些帮助.先后顺序与问题的重要性无关,查看的时候,最好是全面了解一下 ...

  10. 经典c程序100例==51--60

    [程序51] 题目:学习使用按位与 & . 1.程序分析:0&0=0; 0&1=0; 1&0=0; 1&1=1 2.程序源代码: #include " ...