1. 线程创建
- 继承Thread类,重写run()方法
- 实现Runnable接口,重写run()方法
通常用实现Runnable接口的方式创建线程,这样创建的优势在于:
- 适合多个线程共享同一个资源
- 避免Java单继承的局限性
- 增加程序的健壮性,实现解耦
- 线程池只能放入实现Runnable或Callable的线程
2. 线程状态(生命周期)
2.1 状态列表
线程状态 | 导致状态发生条件 |
---|---|
NEW | 线程刚被创建,未调用start方法 |
RUNNABLE | 线程可以在java虚拟机中运行的状态 |
BLOCKED | 当一个线程试图获取一个对象锁,而该对象锁被其他的线程持有,则该线程进入Blocked状态;当该线程持有锁时,该线程将变成Runnable状态 |
WAITING | 一个线程在等待其他线程唤醒时,导致该状态常见方法有:Object.wait;Thread.join;LockSupport.park |
TIMED_WAITING | 定时等待,常见方法有Thread.sleep和无限等待中方法加时间参数 |
TERMINATED | 因为run方法正常退出而死亡,或者因为没有捕获的异常终止了run方法而死亡 |
注:该状态描述详见Thread类中State枚举类,jdk版本为1.5之后
2.2 状态转换
3. 线程常用方法
3.1 线程静态方法
- sleep():线程休眠,可设定时间长度
- currentThread():获取当前线程
- activeCount():当前线程组活跃线程数
- yield():暂停当前线程,重新抢夺cpu
/**
* @Description 线程常见api
* @Author lin
* @Date 2021/2/28 15:15
*/
public class ThreadAPI {
public static void main(String[] args) {
//获取当前线程对象
System.out.println(Thread.currentThread());//Thread[main,5,main]:线程对象[线程名称,线程优先级,线程所在的线程组]
//通过当前的线程对象来获取到相关信息
System.out.println(Thread.currentThread().getId());//获取到线程的id标识符
System.out.println(Thread.currentThread().getName());//获取到线程的名称
System.out.println(Thread.currentThread().getPriority());//获取到线程的优先级
System.out.println(Thread.currentThread().getState());//获取到线程的状态
System.out.println(Thread.currentThread().getThreadGroup());//获取到线程的线程组
System.out.println(Thread.activeCount());//获取到当前线程所在线程组的活动线程的数量
System.out.println("------------------------------------------------------------------");
//三个线程打印结果:YZ交错打印,X最后打印
new Thread(() -> {
for (int i = 0; i < 20; i++) {
//调用sleep方法
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程X:"+i);
}
}).start();
new Thread(() -> {
for (int i = 0; i < 20; i++) {
System.out.println("线程Y:"+i);
//调用yield方法
Thread.yield();
}
}).start();
new Thread(() -> {
for (int i = 0; i < 20; i++) {
System.out.println("线程Z:"+i);
//调用yield方法
Thread.yield();
}
}).start();
}
}
3.2 获取线程信息方法
- getName()/setName():获取/设置线程名称
- getId():获取线程id
- getPriority()/setPriority():获取/设置线程优先级
- getState():获取线程状态
- setDaemon(boolean on):将该线程标记为守护线程
/**
* @Description 守护线程演示
* 1、守护线程也称之为后台线程或用户线程;
* 2、当其他线程都结束时,守护线程会会自动结束,最典型的守护线程就是垃圾回收线程;
* 3、守护线程必须在start方法调用之前来设置;
* @Author lin
* @Date 2021/2/28 15:11
*/
public class DeamonDemo {
public static void main(String[] args) {
//创建一个多线程,设置为守护线程
Thread deamonThread = new Thread(() -> {
//让该线程进行死循环,不终止
while(true) {
try {
Thread.sleep(1000);
System.out.println("守护线程正在执行中...");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
deamonThread.setDaemon(true);
//创建一个前台线程
Thread t1 = new Thread(() -> {
for (int i = 0; i < 50; i++) {
try {
Thread.sleep(50);
System.out.println("线程A:"+i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
if (deamonThread.isDaemon()) {
deamonThread.start();
t1.start();
}
}
}