⭐ 作者:小胡_不糊涂
🌱 作者主页:小胡_不糊涂的个人主页
📀 收录专栏:JavaEE
💖 持续更文,关注博主少走弯路,谢谢大家支持 💖
Thread
- 1. 线程创建
- 1.1 继承Thread类
- 1.2 实现Runnable接口
- 1.3 使用匿名内部类创建Thread子类对象
- 1.4 使用匿名类创建 Runnable 子类对象
- 1.5 使用lambda 表达式
- 2. 线程中断
- 2.1 使用自定义的变量来作为标记位
- 2.2 调用interrupt()方法来通知
- 3. 线程等待-join()
- 4. 线程休眠-sleep()
- 5. 获取线程实例
1. 线程创建
1.1 继承Thread类
class MyThread extends Thread{
public void run(){
System.out.println("继承Thread,重写run");
}
}
public class TestDemo1{
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start();//启动线程
}
}
1.2 实现Runnable接口
class MyRunnable implements Runnable{
public void run(){
System.out.println("实现Runnable接口");
}
}
public class TestDemo1{
public static void main(String[] args) {
Thread thread=new Thread(new MyRunnable());
thread.start();
}
}
1.3 使用匿名内部类创建Thread子类对象
public class TestDemo1{
public static void main(String[] args) {
Thread thread=new Thread(){
public void run(){
System.out.println("这是一个线程");
}
};
thread.start();
}
}
1.4 使用匿名类创建 Runnable 子类对象
public class TestDemo1{
public static void main(String[] args) {
Thread thread=new Thread(new Runnable(){
public void run() {
System.out.println("实现Runnable,重写run,使用匿名内部类");
}
});
thread.start();//启动线程
}
}
1.5 使用lambda 表达式
public class TestDemo1{
public static void main(String[] args) {
Thread thread=new Thread(()->{
System.out.println("使用lambda表达式");
});
thread.start();
}
}
2. 线程中断
当我们想要让一个正在执行的线程停止时,该怎么做呢?
2.1 使用自定义的变量来作为标记位
ublic class TestDemo2 {
private static volatile boolean isquit=false;
public static void main(String[] args) {
Thread thread=new Thread(()->{
while(!isquit){
System.out.print(Thread.currentThread().getName());
System.out.println("线程工作中...");
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
//线程运行完毕
System.out.println("线程工作完毕");
});
thread.start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
isquit = true;
System.out.println("让 thread 线程结束!");
}
}
需要给标志位上加 volatile 关键字才能进行修改
2.2 调用interrupt()方法来通知
方法 | 说明 |
---|---|
public void interrupt() | 中断对象关联的线程 |
public static boolean interrupted() | 判断当前线程的中断标志位是否设置 |
public bool isInterrupted() | 判断对象关联的线程标志位是否设置 |
public class TestDemo2 {
public static void main(String[] args) throws InterruptedException {
Thread thread=new Thread(()-> {
//while(!Thread.interrupted()){
while (!Thread.currentThread().isInterrupted()) {
System.out.println("线程工作中...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
break;
}
}
});
thread.start();
Thread.sleep(2000);
// 使用一个 interrupt 方法, 来修改刚才标志位的值
System.out.println("让 thread 线程结束");
thread.interrupt();
}
}
thread 收到通知的⽅式有两种:
- 如果线程因为调⽤ wait/join/sleep 等⽅法⽽阻塞挂起,则以 InterruptedException 异常的形式通知,清除中断标志。
当出现 InterruptedException 的时候,要不要结束线程取决于catch 中代码的写法。可以选择忽略这个异常,也可以跳出循环结束线程。 - 否则,只是内部的⼀个中断标志被设置,thread 可以通过。
Thread.currentThread().isInterrupted()判断指定线程的中断标志被设置,不清除中断标志,这种方式通知收到的更及时,即使线程正在 sleep 也可以马上收到。
3. 线程等待-join()
有时,我们需要等待⼀个线程完成它的⼯作后,才能进⾏⾃⼰的下⼀步⼯作。
public class TestDemo3{
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(() -> {
int n = 5;
for (int i = 0; i < n; i++) {
System.out.println("我是一个线程, 正在工作中...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("线程执行结束");
});
t.start();
t.join(); // 线程等待
System.out.println("这是主线程, 期望在 thread 结束后打印");
}
}
如果将t.join()
注释,结果会是什么呢?
方法 | 说明 |
---|---|
public void join() | 等待线程结束 |
public void join(long millis) | 等待线程结束,最多等待millis毫秒 |
public void join(long millis,int nanos) | 同上 |
4. 线程休眠-sleep()
为线程的调度是不可控的,所以,该⽅法只能保证实际休眠时间是⼤于等于参数设置的休眠时间的。
方法 | 说明 |
---|---|
public static void sleep(long millis) throws InterruptedException | 休眠当前线程run方法 |
public static void sleep(long millis,int nanos) throws InterruptedException | 可以更高精度的休眠线程 |
public class TestDemo4 {
public static void main(String[] args) throws InterruptedException {
Thread t1=new Thread(()->{
System.out.println("t1正在执行");
});
Thread t2=new Thread(()->{
System.out.println("t2正在执行");
});
t1.start();
t2.start();
}
}
上面的执行过程中,我们无法控制t1与t2的先后执行顺序,运行时就会产生:
但是当我们让main线程在执行t1线程时,进入有限的休眠状态,就可以保证t2不会来干扰t1
public class TestDemo4 {
public static void main(String[] args) throws InterruptedException {
Thread t1=new Thread(()->{
System.out.println("t1正在执行");
});
Thread t2=new Thread(()->{
System.out.println("t2正在执行");
});
t1.start();
Thread.sleep(1000);
t2.start();
}
}
5. 获取线程实例
方法 | 说明 |
---|---|
public static Thread currentThread(); | 返回当前线程对象的引用 |
public class TestDemo5 {
public static void main(String[] args) {
Thread thread=Thread.currentThread();
System.out.println(thread.getId());//1
System.out.println(thread.getName());//main
}
}
public class TestDemo5 {
public static void main(String[] args) {
// Thread thread=Thread.currentThread();
Thread thread=new Thread();
System.out.println(thread.currentThread().getId());//1
System.out.println(thread.getName());//Thread-0
}
}