一.线程的创建
继承Thread类
//继承Thread类class MyThread extends Thread{@Overridepublic void run() {System.out.println("线程运行的代码");}
}
public class Demo1 {public static void main(String[] args) {MyThread t = new MyThread();t.start();//启动线程,此时被创建System.out.println("main执行的方法");}}
实现Runnab接口
//实现Runnab接口
class MyRunnable implements Runnable{@Overridepublic void run() {System.out.println("这是线程执行的代码");}
}
public class Demo2 {public static void main(String[] args) {Thread t = new Thread(new MyRunnable());t.start();System.out.println("这是main执行的代码");}}
匿名内部类创建Thread子类对象
public class Demo3 {public static void main(String[] args) {Thread t = new Thread(){@Overridepublic void run() {System.out.println("这是线程执行的代码");}};t.start();System.out.println("这是main执行的方法");}
}
匿名内部类创建Runnable接口
public class Demo4 {public static void main(String[] args) {Thread t = new Thread(new Runnable() {@Overridepublic void run() {System.out.println("这是线程执行的代码");}});t.start();System.out.println("这是main执行的代码");}}
lambda表达式创建Runnab子类对象
public class Demo5 {public static void main(String[] args) {Thread t = new Thread(() -> {System.out.println("这是线程执行代码");});t.start();System.out.println("这是main执行代码");}
}
二.获取当前线程的实例
public static Thread currentThread() | 返回当前对象的引用 |
public static void main(String[] args) {Thread t = new Thread(() -> {Thread thread = Thread.currentThread();System.out.println(thread.getName());},"t线程");t.start();}
执行结果:
t线程
三.线程中断
使用自定义的标志位中断线程
public class Demo7 {public static boolean isQuit = false;//设置自定义标志位public static void main(String[] args) {Thread t = new Thread(() ->{while (!isQuit){System.out.println("线程代码");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});t.start();try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}isQuit = true; //设置标志位System.out.println("标志位设置,线程执行结束");}
}
代码运行结果
线程代码
线程代码
标志位设置,线程执行结束
使用Thread.interrupted()或者Thread.currentThread().isInterrupted()代替自定义标志位
方法 | 说明 | ||||||||
public void interrut() | 中断对象关联的线程,如果该线程阻塞,则异常通知,否则设置标志位 | ||||||||
public static boolean interrupted() | 判断当前线程中断标志位是否设置,调用后清除标志位 | ||||||||
public boolean isinterrupted() | 判断对象关联的线程的标志位是否设置,调用后不清除标志位 |
使用示例
使用Thread.interrupted()作为中断标志位
public static void main(String[] args) {Thread t = new Thread(() -> {while (!Thread.interrupted()){System.out.println("线程执行");}});t.start();try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}t.interrupt(); //设置中断标志位}
}
使用Thread.currentThread().isInterrupted()
public static void main(String[] args) {Thread t = new Thread(() -> {while (!Thread.currentThread().isInterrupted()){System.out.println("线程执行");}});t.start();try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}t.interrupt(); //设置中断标志位}
}
Thread.currentThread().isInterrupted()与Thread.interrupted()的区别
Thread.interrupted()调用后,清除标志位
Thread.currentThread().isInterrupted()调用后,保留标志位
public static void main(String[] args) {Thread t = new Thread(() -> {for (int i = 0; i < 3; i++) {System.out.println(Thread.interrupted());}});t.start();t.interrupt();}
执行结果
true
false
false
public static void main(String[] args) {Thread t = new Thread(() -> {for (int i = 0; i < 3; i++) {System.out.println(Thread.currentThread().isInterrupted());}});t.start();t.interrupt();}
执行结果
true
true
true
注意
当线程因为调用wait/join/sleep等方法阻塞时,会以InterruptedException的异常通知,并且清除中断标志位,是否需要结束线程,取决catch中的写法,加上break结束线程,或者直接忽略继续向下执行
public static void main(String[] args) {Thread t = new Thread(() -> {while (!Thread.currentThread().isInterrupted()){System.out.println("线程执行");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});t.start();try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}t.interrupt(); //设置中断标志位}
执行结果:
线程执行
线程执行
线程执行
java.lang.InterruptedException: sleep interruptedat java.lang.Thread.sleep(Native Method)at Demo8.lambda$main$0(Demo8.java:14)at java.lang.Thread.run(Thread.java:748)
线程执行
线程执行
线程执行
四.线程等待
public void join() | 等待线程结束 | ||||
public void join(毫秒) | 等待线程结束,最多等毫秒,超过时间不等待 |
线程1在main中调用join,目的是让main等待线程1结束再继续执行
未调用join
public static void main(String[] args) {Thread t1 = new Thread(() -> {for (int i = 0; i < 2; i++) {System.out.println("线程1执行");}});t1.start();System.out.println("线程1执行完了");}
执行结果:
线程1执行完了
线程1执行
线程1执行调用joinpublic static void main(String[] args) {Thread t1 = new Thread(() -> {for (int i = 0; i < 2; i++) {System.out.println("线程1执行");}});t1.start();try {t1.join();} catch (InterruptedException e) {e.printStackTrace();}System.out.println("线程1执行完了");}
执行结果:
线程1执行
线程1执行
线程1执行完了
五.线程休眠
public static void sleep(毫秒) | Thread类方法,休眠当前线程,会抛异常,因为线程调度不可控,所以实际休眠时间接近设置的时间 |
public static void main(String[] args) {Thread t1 = new Thread(() -> {for (int i = 0; i < 3; i++) {System.out.println("线程执行");try {Thread.sleep(1000);System.out.println("休眠1s");} catch (InterruptedException e) {e.printStackTrace();}}});t1.start();}
执行结果:
线程执行
休眠1s
线程执行
休眠1s
线程执行
休眠1s