Thread 类的基本用法
目录
1.线程创建
1.继承 Thread, 重写 run
2.实现 Runnable, 重写 run
3.继承 Thread, 重写 run, 使用匿名内部类
4.实现 Runnable, 重写 run, 使用匿名内部类
5.使用 lambda 表达式
2.线程中断
2.1给线程中设定一个结束标志位
2.2调用 interrupt() 方法来通知
3.线程等待
4.线程休眠
5.获取线程实例
1.线程创建
1.继承 Thread, 重写 run
class MyThread extends Thread{
@Override
public void run() {
while(true){
System.out.println("hello t");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class test1 {
public static void main(String[] args) {
Thread t=new MyThread();
t.start();
while(true){
System.out.println("hello main");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
2.实现 Runnable, 重写 run
class MyRunnable implements Runnable{
@Override
public void run() {
while(true){
System.out.println("hello t");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class test2 {
public static void main(String[] args) {
MyRunnable runnable=new MyRunnable();
Thread t=new Thread(runnable);
t.start();
System.out.println("hello main");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
3.继承 Thread, 重写 run, 使用匿名内部类
public class test3 {
public static void main(String[] args) {
Thread t=new Thread(){
@Override
public void run() {
while(true){
System.out.println("hello t");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
t.start();
while(true){
System.out.println("hello main");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
4.实现 Runnable, 重写 run, 使用匿名内部类
public class test4 {
public static void main(String[] args) {
Thread t=new Thread(new Runnable() {
@Override
public void run() {
while(true){
System.out.println("hello t");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
t.start();
while(true){
System.out.println("hello main");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
5.使用 lambda 表达式
public class test5 {
public static void main(String[] args) {
Thread t=new Thread(()->{
while(true){
System.out.println("hello t");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t.start();
while(true){
System.out.println("hello main");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
2.线程中断
让一个线程停下来,线程的终止
本质上,线程终止办法就一种,让线程的入口方法执行完毕
2.1给线程中设定一个结束标志位
while(true){
...
}
死循环,导致入口方法无法执行完毕
解决方法
blic 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 线程终止");
});
t.start();
//在主线程中,修改isQuit
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
isQuit=true;
}
#
#
" class="reference-link">
2.2调用 interrupt() 方法来通知
interrupt方法的作用:
1.设置标志位为true
2.如果该线程正在阻塞中(比如在执行sleep)
public static void main(String[] args) {
Thread t=new Thread(() ->{
//currentThread是获取到当前线程实例
//currentThread得到的对象是t
//isInterrupted是t对象里自带的一个标志位
while(!Thread.currentThread().isInterrupted()){
System.out.println("hello t");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
break;
//如果要结束循环,要在catch中加break
}
}
});
t.start();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//把t内部的标志位设置为true
t.interrupt();
}
此时会把阻塞状态唤醒
通过抛出异常的方法让sleep立即结束
当sleep被唤醒时,sleep会自动把isInterrupted标志位给清空(true->false)
观察标志位是否清除:
如果sleep执行时,标志位为false,sleep正常休眠
如果标志位为true,无论sleep刚执行或执行一半:
1.立刻抛出异常
2.清空标志位为false
下次循环到sleep,由于标志位本身是false,就什么都不干
多线程执行顺序:
每个线程都是独立执行,执行到start方法,代码兵分两路,主线程继续执行,新线程进入到run方法执行,主线程执行完interrupt,继续往后执行,不会再到interrupt
interrupt只是通知,不是”命令”,是否结束由代码来灵活控制
3.线程等待
线程之间并发执行,操作系统对线程的调度,无法确定哪个线程先执行结束
用线程等待可以规定结束顺序:如果t1线程中,调用t2.join,是让t1线程等待t2结束
Thread t=new Thread(()->{
System.out.println("t");
});
t.start();
t.join();
//在main中调用t.join,是让main线程等待t先结束,在往下执行
//在t.join执行,如果t线程还没结束,main线程会阻塞等待
System.out.println("main");
1.main线程调用tjoin的时候,如果t还执行
此时main线程阻塞,再到t执行完毕(t的run执行完了),main才从阻塞中解除,才执行
2.main线程调用t.join的时候,如果t结束
此时join不会阻塞,会立即往下执行
都保证t是先结束的
join还有一个有参的版本,填写一个参数,作为超时时间,最大等待时间
如果等待时间到达上限,还没等待,就不等了
4.线程休眠
方法 | 说明 |
public static void sleep(long millis) throws InterruptedException | 休眠当前线程 millis 毫秒 |
public static void sleep(long millis, int nanos) throws InterruptedException | 可以更高精度的休眠 |
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
break;
//如果要结束循环,要在catch中加break
}
5.获取线程实例
方法 | 说明 |
public static Thread currentThread(); | 返回当前线程对象的引用 |
public static void main(String[] args) {
Thread thread = Thread.currentThread();
System.out.println(thread.getName());
}
还没有评论,来说两句吧...