——————————————————————————————————————————————————————————————————————
主要介绍Thread类常见的构造方法、属性、方法
一、Thread类的构造方法
方法 | 说明 |
---|---|
Thread( ) | 直接创建线程对象 |
Thread( String name ) | 直接创建线程对象,并定义线程名称 |
Thread( Runnable Target ) | 使用Runnable对象创建线程对象 |
Thread( Runnable Target, String name ) | 使用Runnable对象创建线程对象,并定义线程名称 |
public class ThreadDemo1 {
public static void main(String[] args) {
//直接创建线程
Thread thread1 = new Thread();
Thread thread2 = new Thread("命名");
//通过使用Runnable对象创建创建线程
Thread thread3 = new Thread(new Runnable() {
@Override
public void run() {
}
});
Thread thread4 = new Thread(new Runnable() {
@Override
public void run() {
}
},"命名");
}
}
——————————————————————————————————————————————————————————————————————
以下代码案例均使用Lambda表达式写法,具体内容可参考此篇博客: Java:创建线程的几种方法
二、Thread类的属性
属性 | 方法 |
---|---|
ID | getId( ) |
名称 | getName( ) |
状态 | getState( ) |
优先级 | getPriority( ) |
是否后台线程 | isDaemon( ) |
是否存活 | isAlive( ) |
是否被中断 | isInterrupted( ) |
ID:JVM自动分配的线程序号
public class ThreadDemo2 {
public static void main(String[] args) {
Thread thread = new Thread(() -> {
System.out.println("线程ID:" + Thread.currentThread().getId());
});
thread.start();
}
}
线程ID:21
名称:默认线程名称或自定义名称
public class ThreadDemo2 {
public static void main(String[] args) {
//并未自定义线程名称
Thread thread = new Thread(() -> {
System.out.println("线程名称:" + Thread.currentThread().getName());
});
thread.start();
}
}
线程名称:Thread - 0
状态:NEW、RUNNABLE、BLOCKED、WAITING、TIME_WAITING、TERMINATED状态
关于线程状态可参考此篇文章: Java:线程的几种状态
public class ThreadDemo2 {
public static void main(String[] args) {
Thread thread = new Thread(() -> {
System.out.println("线程状态:" + Thread.currentThread().getState());
});
thread.start();
}
}
线程状态:RUNNABLE
优先级:1-10表示、数字越大优先级越高更容易被调度
public class ThreadDemo2 {
public static void main(String[] args) {
Thread thread = new Thread(() -> {
System.out.println("线程优先级:" + Thread.currentThread().getPriority());
});
thread.start();
}
}
线程优先级:5
是否后台线程:返回boolean类型,后台进程不会阻止JVM的退出,多用于辅助
public class ThreadDemo2 {
public static void main(String[] args) {
Thread thread = new Thread(() -> {
System.out.println("后台线程:" + Thread.currentThread().isDaemon());
});
thread.start();
}
}
后台进程:false
是否存活:返回boolean类型,在run方法执行完毕之前都处于存活状态
public class ThreadDemo2 {
public static void main(String[] args) {
Thread thread = new Thread(() -> {
System.out.println("存活:" + Thread.currentThread().isAlive());
});
thread.start();
}
}
存活:true
是否被中断:线程调用interrupted( )方法后,可用isInterrupted( )方法来检测是否中断
public class ThreadDemo2 {
public static void main(String[] args) {
Thread thread = new Thread(() -> {
System.out.println("中断:" + Thread.currentThread().isInterrupted());
});
thread.start();
}
}
中断:false
三、Thread类方法
作用 | 方法 |
---|---|
线程启动 | start( ) |
线程等待 | join( ) |
线程休眠 | sleep( ) |
线程中断 | interrupted( ) |
返回当前线程对象的引用 | currentThread( ) |
线程启动
run( )和start( )的区别:调用Thread的构造方法为了创建一个线程对象,重写run方法是提供线程索所要做的事情而不是线程开始运行,只有调用start方法是线程才真正运行起来
🌰:有一天老板把小刘叫到办公室,对小刘公司需要点现金💰你去银行取来,小刘听闻立马赶去银行🏦取来
在此过程中“叫小刘”就是创建线程,“吩咐小刘去取现金”这是重写run方法,“小刘去取钱”这是线程运行。
public class ThreadDemo3 {
public static void main(String[] args) {
Thread thread = new Thread(() -> {
System.out.println("线程开始启动!");
});
thread.start();
}
}
线程开始启动!
线程等待
在多线程操作中,有时需要按不同的顺序执行,未执行的线程则进入阻塞状态等待执行线程完毕
🌰:线程A和线程B,A负责打印10中的偶数,B负责打印10中的奇数,规定先打印完偶数在打印奇数,因此就需要B等待A运行完毕后再执行。
join构造方法中含有设定等待时常功能,只需在括号中传递参数即可,单位为毫秒ms
public class ThreadDemo3 {
public static void main(String[] args) {
Thread A = new Thread(() -> {
System.out.println("偶数:");
for(int i = 0; i < 10; i++) {
if(i % 2 == 0) {
System.out.print(i);
}
}
System.out.println();
});
Thread B = new Thread(() -> {
try {
//start方法是操作系统随机调度的,并不能确定线程的运行顺序
//在线程B中调用线程A的join方法会导致线程B进入阻塞状态、当线程A执行完毕后,线程B从阻塞状态中释放出来,正常运行
A.join();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("奇数:");
for(int i = 0; i < 10; i++) {
if(i % 2 != 0) {
System.out.print(i);
}
}
System.out.println();
});
A.start();
B.start();
}
}
偶数:
02468
奇数:
13579
线程休眠
Thread类中的静态方法,使当前线程进入休眠状态,让出CPU资源去执行其它线程
🌰:接着用上面打印奇偶数的例子,俩个线程同时运行,不能确定打印顺序,调用sleep方法使线程B进入休眠状态,AB线程同时运行,线程B进入休眠状态5秒后继续执行。单位为毫秒ms
public class ThreadDemo3 {
public static void main(String[] args) {
Thread A = new Thread(() -> {
System.out.println("偶数:");
for(int i = 0; i < 10; i++) {
if(i % 2 ==0) {
System.out.print(i);
}
}
System.out.println();
});
Thread B = new Thread(() -> {
try {
//线程B5秒后继续执行
Thread.sleep(5000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("奇数:");
for(int i = 0; i < 10; i++) {
if(i % 2 != 0) {
System.out.print(i);
}
}
System.out.println();
});
A.start();
B.start();
}
}
偶数:
02468
奇数:
13579
线程中断
线程中断不一定立即停止线程的执行,而是设置线程的中断状态,由线程本身决定如何响应这个状态
1.当线程正处于wait/join/sleep等阻塞状态时,在调用interrupted方法则会抛出InterruptedException异常清除中断标识,是否结束线程取决于cathch中的代码逻辑。
2.设置中断状态,不做过多处理,可以通过isInterrputed方法来判断当前线程的中断状态。
🌰:线程打印0-5数字,每打印一个数字休眠1s,在启动线程后休眠3s执行interrupted操作,最终结果为打印前三个数字
public class ThreadDemo3 {
public static void main(String[] args) throws InterruptedException {
Thread A = new Thread(() -> {
System.out.println("偶数:");
for(int i = 0; i < 5; i++) {
try {
System.out.println(i);
Thread.sleep(1000);
} catch (InterruptedException e) {
//主要取决于catch中代码逻辑,此处案例为抛出异常停止打印,结束线程
System.out.println("停止打印");
throw new RuntimeException(e);
}
}
System.out.println();
});
A.start();
//休眠3s后执行interrupted方法
Thread.sleep(3000);
A.interrupt();
}
}
获取当前线程对象的引用
Thread类中的静态方法,主要用于在当前线程中获取线程的属性和状态等
public class ThreadDemo3 {
public static void main(String[] args) {
Thread thread = new Thread(() -> {
System.out.println(Thread.currentThread().getId());
System.out.println(Thread.currentThread().getName());
System.out.println(Thread.currentThread().getState());
});
thread.start();
}
}
21
Thread-0
RUNNABLE