文章目录
- 1.线程和进程的区别
- 2.创建线程
- 2.1Thread类
- 2.2Runnable接口
- 2.3匿名类创建Thread子类对象
- 创建后台线程
- 3.Thread常⻅⽅法
- 4.中断线程
- 4.1中断标记(Interrupt Flag)
- 4.2调⽤ interrupt() ⽅法
- 5.线程状态
1.线程和进程的区别
1.进程中包含线程,一个进程中至少一个线程(主线程)
2.进程是申请系统资源的最小单位
3.线程是CPU调度的最小单位
4.线程之间共享进程申请的系统资源
5.一个线程崩溃,会影响整个进程
2.创建线程
2.1Thread类
public static void main(String[] args) throws InterruptedException {
Mythred mythred = new Mythred();
//开启线程
mythred.start();
//main方法中的循环
while (true) {
Thread.sleep(1000);
System.out.println("同时进行");
}
}
static class Mythred extends Thread {
@Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("测试");
}
}
}
2.2Runnable接口
public static void main(String[] args) {
MyRunnable01 myRunnable01=new MyRunnable01();
MyRunnable02 myRunnable02=new MyRunnable02();
Thread thread01=new Thread(myRunnable01);
Thread thread02=new Thread(myRunnable01);
Thread thread03=new Thread(myRunnable02);
thread01.start();
thread02.start();
thread03.start();
}
static class MyRunnable01 implements Runnable{
public void run() {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("产生服装,金币+50");
}
}
}
static class MyRunnable02 implements Runnable{
public void run() {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("产生墨镜,金币+10");
}
}
}
2.3匿名类创建Thread子类对象
import java.lang.invoke.LambdaConversionException;
public class test5 {
public static void main1(String[] args) {
Thread thread=new Thread(){
public void run(){
System.out.println("通过匿名内部类(Thread)实现");
}
};
thread.start();
}
public static void main2(String[] args) {
Thread thread=new Thread(new Runnable() {
public void run() {
System.out.println("通过匿名内部类(Runnable)实现");
}
});
thread.start();
}
public static void main(String[] args) {
Thread thread=new Thread(() ->{
System.out.println("通过Lambda实现");
});
thread.start();
}
}
创建后台线程
自动终止:后台线程不会阻止JVM的退出。如果所有的用户线程都结束了,JVM会自动关闭,即使后台线程仍在运行。
优先级:后台线程的优先级通常较低,但这并不是强制的。你可以通过Thread.setPriority()方法设置线程的优先级。
使用场景:后台线程通常用于执行一些辅助任务,比如垃圾回收、日志记录、监控等
在设置线程为后台线程之前,必须先调用start()方法,否则会抛出IllegalThreadStateException。
后台线程的运行时间不应过长,因为它们可能在JVM关闭时被强制终止,可能导致数据丢失或状态不一致。
不建议在后台线程中执行需要保证完成的任务,例如文件写入或数据库操作。
Thread thread = new Thread(() -> {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("啦啦啦");
}
}, "这是我的名字");
//设置为后台线程
thread.setDaemon(true);
System.out.println("线程是否存活:"+thread.isAlive());
thread.start();
System.out.println("线程是否存活:"+thread.isAlive());
System.out.println("mian方法完成:");
3.Thread常⻅⽅法
• ID 是线程的唯⼀标识,不同线程不会重复
• 名称是各种调试⼯具⽤到
• 状态表⽰线程当前所处的⼀个情况,下⾯我们会进⼀步说明
• 优先级⾼的线程理论上来说更容易被调度到
• 关于后台线程,需要记住⼀点:JVM会在⼀个进程的所有⾮后台线程结束后,才会结束运⾏。
• 是否存活,即简单的理解,为 run ⽅法是否运⾏结束了
public static void main(String[] args) {
Thread thread = new Thread (()->{
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("啦啦啦");
}
},"这是我的名字");
thread.start();
System.out.println("线程名称:"+thread.getName());
System.out.println("线程序号:"+thread.getId());
System.out.println("线程优先级:"+thread.getPriority());
System.out.println("线程状态:"+thread.getState());
System.out.println("线程是否存活:"+thread.isAlive());
System.out.println("线程是否被中断:"+thread.isInterrupted());
}
4.中断线程
4.1中断标记(Interrupt Flag)
使用变量去中断
static boolean flg=false;
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread (()->{
while (!flg) {
try {
System.out.println("啦啦啦");
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.println("线程已退出");
},"这是我的名字");
thread.start();
Thread.sleep(4000);
flg=true;
}
4.2调⽤ interrupt() ⽅法
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(() -> {
while (!Thread.currentThread().isInterrupted()) {
System.out.println("啦啦啦");
try {
Thread.sleep(1000);//大部分时间停留在睡眠
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("休眠被中断");
break;
}
System.out.println("线程结束");
}
}, "这是我的名字");
System.out.println("线程是否存活:"+thread.isAlive());
thread.start();
//使线程休眠会
Thread.sleep(1000);
System.out.println("线程是否存活:"+thread.isAlive());
//中断线程
thread.interrupt();
//等待线程被销毁
Thread.sleep(1000);
System.out.println("线程是否存活:"+thread.isAlive());
}
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(() -> {
while (!Thread.currentThread().isInterrupted()) {
System.out.println("啦啦啦");
}
System.out.println("线程结束");
}, "这是我的名字");
System.out.println("线程是否存活:"+thread.isAlive());
thread.start();
System.out.println("线程是否存活:"+thread.isAlive());
Thread.sleep(2);
//中断线程
thread.interrupt();
//等待线程被销毁
Thread.sleep(100);
System.out.println("线程是否存活:"+thread.isAlive());
}
interrupt() 标准、安全,支持阻塞状态响应 需主动检查中断标志 需协作终止的线程
volatile 标志位 简单直观 无法响应阻塞状态 无阻塞任务的线程
5.线程状态
1.NEW:表示创建好了一个java线程对象,安排好了任务,但是还没有启动,没有调用start()方法之前不创建PCB。
2.RUNNABLE:运行+就绪状态,在系统中有对应PCB
**3.BLOCKED:**等待锁的状态,阻塞中的一种
**4.WATING:**线程因为调用了Object.wait()、Thread.join()或LockSupport.park()方法而进入等待状态。线程会一直等待,直到其他线程显式地唤醒它。
**5.TIMED_WATING:**指定等待时间的阻塞状态,线程因为调用了带有超时参数的Object.wait(long)、Thread.join(long)、Thread.sleep(long)或LockSupport.parkNanos()等方法而进入计时等待状态。线程会在指定的时间后自动唤醒,或者被其他线程提前唤醒。
6.TERMINATED:结束,PCB已经被销毁,但是java线程对象还在。
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread (()->{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
System.out.println("线程状态"+thread.getState());
thread.start();
System.out.println("线程状态"+thread.getState());
Thread.sleep(100);
// 主线程休眠,确保子线程进入TIMED_WAITING状态
System.out.println("线程状态"+thread.getState());
thread.join();
System.out.println("线程状态"+thread.getState());
}