建设项目公示网站,建站公司山东济南兴田德润简介,可以做旅游攻略的网站,wordpress cia易验证Thread类是JVM用来管理线程的一个类,换句话说,每个线程都唯一对应着一个Thread对象.
因此,认识和掌握Thread类弥足重要.
本文将从
线程创建线程中断线程等待线程休眠获取线程实例
等方面来进行具体说明. 1)线程创建 方法1:通过创建Thread类的子类并重写run () 方法
class M…Thread类是JVM用来管理线程的一个类,换句话说,每个线程都唯一对应着一个Thread对象.
因此,认识和掌握Thread类弥足重要.
本文将从
线程创建线程中断线程等待线程休眠获取线程实例
等方面来进行具体说明. 1)线程创建 方法1:通过创建Thread类的子类并重写run () 方法
class MyThread extends Thread{Overridepublic void run() {System.out.println(thread);}
}
public class Thread1 {public static void main(String[] args) {Thread thread new MyThread();thread.start();System.out.println(main);}
}
方法2:通过创建Runnable接口的实现类并重写run ()方法,传实现类的对象作为构造器
class MyRunnable implements Runnable{Overridepublic void run() {System.out.println(thread);}
}
public class Thread2 {public static void main(String[] args) {Thread thread new Thread(new MyThread());thread.start();System.out.println(main);}
}
方法3:使用匿名类,new类,也就是创建该类的子类
public class Thread3 {public static void main(String[] args) {Thread thread new Thread(){Overridepublic void run() {System.out.println(thread);}};thread.start();System.out.println(main);}
}
方法4:使用匿名内部类,new接口,也就是创建该接口的实现类
public class Thread4 {public static void main(String[] args) {Thread thread new Thread(new Runnable() {Overridepublic void run() {System.out.println(thread);}});thread.start();System.out.println(main);}
}
方法5:使用lambda表达式(日常开发中使用最多的形式)
public class Thread5 {public static void main(String[] args) {Thread thread new Thread(()-{System.out.println(thread);});thread.start();System.out.println(main);}
} 2)线程中断 顾名思义,也就是让线程停止.
本质上而言,让线程停止,方法就一种 --执行完线程入口方法(run ()方法).
只不过此处可能是正常执行结束,也可能是因为异常而导致结束.
目前常见的有以下两种方式: 1.使用自定义的变量来作为标志位 2.使用Thread提供的变量来作为标志位
下面来介绍:
方法1.使用自定义的变量来作为标志位
public class ThreadDemo9 {public static boolean isQuit false;public static void main(String[] args) {// boolean isQuit false;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();// 在主线程中, 修改 isQuittry {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}isQuit true;}
}
执行结果: 此处代码的逻辑大概就是,主线程sleep ()3秒后,t线程里的循环差不多执行3次(sleep()了3秒),此时isQUit被置为ture,t线程里循环结束.t线程继续向下执行逻辑,最终t线程正常结束.
假设:此处设置的isQuti不是类变量,而是局部变量,可行吗?
结果是显然不行的.那到底是什么原因呢?其实是因为--lambda表达式存在变量捕获.
变量捕获,只能捕获到由1)final修饰2)实际上final的局部变量.
但是如果该局部变量的值被修改了,那么lamoda表达式就捕获不到该值了.
所以此处该如何做呢? -- 设置成类变量.也就是由static修饰的变量.
因为类变量不受变量捕获的限制. 方法2:使用Thread提供的变量来作为标志位
使用Thread.currentThreadOisInterrupted0 代替自定义标志位.
Thread 内部包含了一个 boolean 类型的变量作为线程是否被中断的标记. public class ThreadDemo10 {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();}}});t.start();try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}// 把 t 内部的标志位给设置成 truet.interrupt();}
} 原因如下:
首先需要明白interrupt 方法的作用:
1)设置标志位为 true
2)如果该线程正在阻塞中(比如在执行 sleep)此时就会把阻塞状态唤醒.通过抛出异常的方式让 sleep 立即结束.(线程在执行sleep(),join (),wait() 方法时,都会进入阻塞状态)
同时需要注意: 当 sleep 被唤醒的时候, sleep 会自动的把 Thread线程内置的标志位给清空(true - false).这就导致下次循环循环仍然可以继续执行了!!!
因此:如果需要结束循环,就得在 catch 中搞个 break.
此处再具体说明一下sleep() 的工作原理:(分3种情况) 1)如果 sleep 执行的时候看到这个标志位是 false -- sleep 正常进行休眠操作.
2)如果当前标志位为 true,sleep 无论是刚刚执行还是已经执行了一半,都会触发两件事 :1.立即抛异常2.清空标志位为 false. 3)如果设置 interrupt 的时候,恰好, sleep 刚醒~~ 这个时候赶巧了,执行到下一轮循环的条件,就直接结束了但是这种概率非常低毕竟 sleep 的时间已经占据了整个循环体的 99.99999999% 的时间了.几乎可以视为不可能事件.
那可能就又会有人问了,为啥 sleep 要清空标志位呢???目的就是为了让线程自身能够对于线程何时结束,有一个更明确的控制~ 当前interrupt 方法,不是让线程立即结束而是告诉他,你该结束了至于他是否真的要结束立即结束还是等会结束都是代码来灵活控制的。 interrupt 只是通知,而不是命令. 为什么这么说呢?原因就是,t线程是否结束,是取决于自身的,也就是说,根据catch里的逻辑实现,可以结束,也可以不结束. 那肯定又会有人问了:那为啥java 这里 不强制设定成命令结束的操作? 只要调用 interrupt 就立即结束??
主要是设定成这种非常不友好的~
线程 t 何时结束,一定是 t 自己最清楚~~ 交给 t 自身来决定比较好~~
映射到生活:如果正在跟领导打电话,你的女票让你去帮她拿东西.那此时,肯定是工作优先嘛!!些竟拿东西不是太重要的事,可以先搁置一会!! 3)线程等待 线程之间是并发执行的,操作系统对于线程的调度是无序的.无法判定两个线程谁先执行结束, 谁后执行结束!!!
在某些业务场景下需要明确规定线程的结束顺序.可以使用线程等待来实现 --join 方法 public class ThreadDemo {public static void main(String[] args) throws InterruptedException {Runnable target () - {for (int i 0; i 10; i) {try {System.out.println(Thread.currentThread().getName() : 我还在工作);Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}System.out.println(Thread.currentThread().getName() : 我结束了);};Thread thread1 new Thread(target, 李四);Thread thread2 new Thread(target, 王五);System.out.println(先让李四开始工作);thread1.start();thread1.join();System.out.println(李四工作结束了让王五开始工作);thread2.start();thread2.join();System.out.println(王五工作结束了);}
}输出结果: 当前是在main线程里执行的thread1.join()(也就是说是让main线程等待thread1线程).
那么在main线程里执行的thread1.join0 的时候,此时有两种情况:
1)如果 thread线程仍在继续运行,那么main线程就会暂时不参与程调度,等待thread1 线程结束main线程才继续执行代码逻辑. 2)如果thread1线程已经结束,那么main线程也就不用等待了,就直接继续执行自己的代码逻辑了.
但不管是哪种情况都能保证thread1线程是先于main线程结束的. 4)线程休眠 方法:public static void sleep(long millis) throws InterruptedException
说明:
1)单位是ms
2)sleep是Thread类里的静态方法,通过类名可以直接调用.
3)作用是休眠当前进程.
4)需要用try-catch处理InterruptedException中断异常(意思就是 sleep 睡眠过程中,还没到点就提前唤醒了). 5)获取线程实例 方法:public static Thread currentThread()
说明:在哪个线程里调用,返回的就是哪个线程的对象引用.
public class ThreadDemo {public static void main(String[] args) {Thread thread Thread.currentThread();System.out.println(thread.getName());}
}
输出结果:main 多提一句:多线程编程在Java中很常见,也很重要.务必掌握!!!
今天不想敲代码,所以才去敲.
uu们加油呀!!