一、线程创建
创建线程最常用的方法是使用lambda表达式
public class Thread {
public static void main(String[] args) {
Thread t = new Thread( ()->{
//方法体
});
t.start();
}
}
二、线程中断
要想使线程中断,方法只有一个:让入口方法执行完毕
而让入口方法执行完毕的操作有两种:
- 设置结束标志位
- 调用interrupt()方法通知
例1:用自定义的变量作为标志位
public class Thread {
//设置标志位
public static boolean isQuit = false;
public static void main(String[] args) {
Thread t = new Thread(() -> {
while(!isQuit) {
System.out.println("hello t");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("线程被中断了");
});
t.start();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//修改标志位
isQuit = true;
}
}
运行结果:
hello t
hello t
hello t
线程被中断了
例2:调用interrupt()
public class Thread {
public static void main(String[] args) {
Thread t = new Thread( ()->{
//currentThread 是获取到当前线程的实例,此处得到的对象就是t
//isInterrupted就是t对象里自带的一个标志位。默认为false
while (!Thread.currentThread().isInterrupted()) {
System.out.println("hello t");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
//break; 加上break,代码出现异常后就结束了
}
}
});
t.start();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//将t内部的标志位设置成true
t.interrupt();
}
}
执行结果:
hello t
hello t
hello t
java.lang.InterruptedException: sleep interrupted
at java.base/java.lang.Thread.sleep(Native Method)
at threading.ThreadDemo10.lambda$main$0(ThreadDemo10.java:9)
at java.base/java.lang.Thread.run(Thread.java:834)
hello t
hello t
hello t
hello t
hello t
hello t
注意:代码被中断后抛出异常,异常结束,循环继续执行,这是因为interrupt()被调用后,通过异常的方式来通知线程中断,而不是强制中断,所以抛出异常后循环仍然执行,若想不执行,在catch代码段中添加break即可。
interrupt方法的作用:
1.设置标志位为true
2.如果该线程正在阻塞中(比如正在执行sleep),此时就会把阻塞状态唤醒。通过抛出异常的方式通知sleep立即结束
判断标志位是否被清除
标志位是否清除, 就类似于一个开关.
Thread.isInterrupted() 判断当前线程的中断标志被设置,相当于按下开关, 开关自动弹起来了. 这个称为 "清除标志位"
Thread.currentThread().isInterrupted() 判断指定线程的中断标志被设置,相当于按下开关之后, 开关弹不起来, 这个称为 "不清除标志位".这种方式通知收到的更及时,即使线程正在 sleep 也可以马上收到。
三、线程等待--join()
线程之间是并发执行的,操作系统对于线程的调度,是无序的,无法判定两个线程谁先执行结束,谁后执行结束
所以有时候就需要明确规定线程的结束顺序。可以用线程等待实现
public class Thread {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread( () -> {
System.out.println("hello t");
});
t.start();
t.join(); //记得抛异常
System.out.println("hello main");
}
}
t.join():实在main线程中调用t.join.意思就是让main线程等待t线程先结束再往下执行
当t线程还没走完时,main线程就会阻塞等待
在A线程里面调用B.join(),就是A等B。别的线程不受影响
join有两个版本:
1>无参数版本:效果是”死等“(不见不散)
2>有参数版本:指定最大超时时间,时间超过未等到就不等了
四、线程休眠--sleep()
方法 | 说明 |
public static void sleep(long mills) throws InterruptedException | 休眠当前线程mills秒 |
public static void sleep(long mills,int nanos) throws InterruptedException | 说明可以更高精度的休眠 |
五、获取线程实例
public static Thread currentThread();
public class Thread{
public static void main(String[] args) {
Thread thread = new Thread.currentThread();
System.out.println(thread.getName());
}
}