概述
目录
1.线程创建
2.线程中断
3.线程等待
4.线程休眠
5.获取线程实例
一.线程创建 start()
1.创建实例
(1)继承Thread 重写run();
class MyThread extends Thread{
public void run(){
while(true){
System.out.println("hello thread");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class demo1 {
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{
public void run(){
while(true){
System.out.println("hello thread");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class demo2 {
public static void main(String[] args) {
Runnable runnable = new MyRunnable();
Thread r = new Thread(runnable);
r.start();
while(true){
System.out.println("hello main");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
(3)继承Thread 重写run() 使用匿名内部类;
public class demo3 {
public static void main(String[] args) {
Thread t = new Thread(){
public void run(){
while(true){
System.out.println("hello thread");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
t.start();
}
}
(4)实现Runnable 重写run() 使用匿名内部类;
public class demo4 {
public static void main(String[] args) {
Runnable runnable = new Runnable() {
@Override
public void run() {
while(true){
System.out.println("hello thread");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
Thread t = new Thread(runnable);
t.start();
}
}
(5)使用lambda表达式;(最推荐的方法!)
public class demo5 {
public static void main(String[] args) {
Thread t = new Thread(()->{
while(true){
System.out.println("hello thread");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t.start();
}
}
创建实例不等于在操作系统内核中创建出了线程,只有调用了start()才是真正的创建出线程。
二.线程中断
线程执行结束:只要让入口方法(main方法)执行完了,线程就随之结束。
(1)直接使用标志位来区分线程是否结束
public class demo9 {
//用boolean变量标识线程是否结束;
private static boolean isQuit = false;
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(()->{
//此时与直接写while(true)并没有什么区别;
while(!isQuit){
System.out.println("线程正在运行中!");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("新线程执行结束!");
});
t.start();
Thread.sleep(1000);
System.out.println("控制新线程退出!");
//将isQuit置为true,则不进入上述循环中,新线程退出!
isQuit = true;
}
}
(2)使用Thread自带的标志位进行区分
interrupt方法的行为:1.如果 t 线程没有处于阻塞状态,interrupt就会修改内置的标志位;2.如果 t线程处于阻塞状态,interrupt就会触发sleep InterruptException;
当线程处于阻塞状态时,借助catch有三种解决方式:立即退出;等一会退出;不退出。
public class demo10 {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(()->{
while(! Thread.currentThread().isInterrupted()){
System.out.println("线程运行中!");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
//立即退出;
//break;
//等一会退出,sleep可以换成任意的收尾代码;
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
break;//等一会退出;
//不退出,啥都不做,忽略异常;
}
}
System.out.println("新线程已经退出!");
});
t.start();
Thread.sleep(1000);
System.out.println("新线程退出!");
t.interrupt();
}
}
除Thread.currentThread().isInterrupted(),还可以使用Thread.interrupt(),不同的是Thread.currentThread().isInterrupted()不会自动清除,而Thread.interrupt()标志位会自动清除,控制它中断后标志位会先设为true,读取的时候会读到这true,但是读完之后这个标志位会自动恢复成false。
三.线程等待 join()
线程之间的执行顺序是完全随机的,由系统的调度决定,此时可以通过join()来控制线程的结束顺序。例如:无法干预调度器的行为,则可以让main线程主动进行等待,即在main线程中调用t1.join()和t2.join(),main阻塞等待t1,t2执行完,main接触阻塞,才能往下执行。
join()方法的行为:1.如果被等待的线程还没执行完,就阻塞等待;2.如果被等待的线程已经执行为了,直接就返回。
public void join() 等待线程结束(死等,没有时间限制);public void join(long millis)等待线程结束,最多等mills毫秒;public void join(long millis,int nanos) 同理,但具有更高精度。
public class demo11 {
//main线程等待t2线程,t2线程等待t1;
private static Thread t1 = null;
private static Thread t2 = null;
public static void main(String[] args) throws InterruptedException {
System.out.println("main begin");
t1 = new Thread(()->{
System.out.println("t1 begin");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("t1 end");
});
t1.start();
t2 = new Thread(()->{
System.out.println("t2 begin");
try {
t1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("t2 end");
});
t2.start();
t2.join();
System.out.println("main end");
}
}
四.线程休眠 sleep()
线程调用sleep()后,会由就绪队列进入阻塞队列,要等到sleep()时间结束,结束后由阻塞队列进入就绪队列,进入就绪队列后可上CPU执行,但是什么时候能上CPU执行的时间不能确定,由系统调度器决定。(PCB是一个双向链表)
五.获取线程实例 currentThread()
为了对线程进行操作(线程等待,线程中断,获取线程属性等),就需要获取到线程引用。如果该线程继承Thread,然后重写run方法,可以直接在run中使用this获取线程实例,但如果使用Runnable或者lambda时,就要使用Thread.currentThread()。
最后
以上就是兴奋灰狼为你收集整理的Thread类的基本用法的全部内容,希望文章能够帮你解决Thread类的基本用法所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复