🎉🎉🎉点进来你就是我的人了
博主主页:🙈🙈🙈戳一戳,欢迎大佬指点!
人生格言:当你的才华撑不起你的野心的时候,你就应该静下心来学习!欢迎志同道合的朋友一起加油喔🦾🦾🦾
目标梦想:进大厂,立志成为一个牛掰的Java程序猿,虽然现在还是一个🐒嘿嘿
谢谢你这么帅气美丽还给我点赞!比个心
目录
前言
一.创建线程的五种方式
1.继承 Thread, 重写 run
2.实现 Runnable, 重写 run
3.继承 Thread, 重写 run, 使用匿名内部类
4.实现 Runnable, 重写 run, 使用匿名内部类
5.使用 lambda 表达式
二.线程的生命周期
三.线程的常见方法
四.Thread类的常见属性的获取方法
五.Thread类的构造方法
六,线程方法的使用
1.前台线程与后台线程
2.中断一个线程
2.1使用自定义标识符来终止线程
2.2使用Thread类自带的标志位(调用 interrupt() 方法来通知)
3. 等待一个线程
4. 线程休眠
5. 获取线程实例
上一篇文章我们讲了Java关于线程的基本知识,接下来给大家分享一些线程是如何创建的以及线程的一些基本用法!
一.创建线程的五种方式
class MyThread extends Thread {@Overridepublic void run() {while (true) {System.out.println("hello-t");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}
}public class ThreadDemo1 {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();}}}
}
class MyRunnable implements Runnable {@Overridepublic void run() {while (true) {System.out.println("hello-t");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}
}
public class ThreadDemo2 {public static void main(String[] args) {MyRunnable runnable =new MyRunnable();Thread t =new Thread(runnable);t.start();while (true) {System.out.println("hello-main");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}
}
public class ThreadDemo3 {public static void main(String[] args) {Thread t =new Thread() {@Overridepublic 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();}}}
}
public class ThreadDemo4 {public static void main(String[] args) {Thread t =new Thread(new Runnable() {@Overridepublic 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();}}}
}
public class ThreadDemo5 {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();}}}
}
二.线程的生命周期
线程开始--》线程消亡
三.线程的常见方法
(1)start() : 启动当前线程,表面上调用start方法,实际在调用线程里面的run方法
(2)run() : 线程类 继承 Thread类 或者 实现Runnable接口的时候,都要重新实现这个run方法,run方法里面是线程要执行的内容
(3)currentThread :Thread类中一个静态方法:获取当前正在执行的线程
(4)setName 设置线程名字
(5)getName 读取线程名字(6)join():当一个线程调用了join方法,这个线程就会先被执行,它执行结束以后才可以去执行其余的线程。
注意:必须先start,再join才有效。
四.Thread类的常见属性的获取方法
(1) getId()
获取线程的ID
(2) getName()
获取线程的名字
(3) getState()
获取线程的状态
(4) getPriority()
获取线程的优先级
(5) isDaemon()
判断线程是否为后台线程(true/false)
注意:JVM的所有非后台进程结束后,才会结束运行该线程
(6) isAlive()
判断线程是否存活(true/false)
(7) isInterrupted()
判断线程是否被中断(true/false)
public class ThreadDemo6 {public static void main(String[] args) throws InterruptedException {Thread thread=new Thread(()->{int count =5;while(count--!=0) {System.out.println("子线程");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}},"thread-0");//设置线程为后台线程thread.setDaemon(true);thread.start();System.out.println("线程的ID(JVM):"+thread.getId());System.out.println("线程的名字:"+thread.getName());//TimeUnit.SECONDS.sleep(1);System.out.println("线程的状态:"+thread.getState());System.out.println("线程的优先级:"+thread.getPriority());System.out.println("线程是否为后台线程:"+thread.isDaemon());//thread.interrupt();System.out.println("线程是否被打断:"+thread.isInterrupted());System.out.println("线程是否存活:"+thread.isAlive());thread.join();System.out.println("线程是否存活:"+thread.isAlive());}
}
五.Thread类的构造方法
方法1:Thread()
创建线程对象
方法2:Thread(Runnable r)
使用Runnable对象创建线程对象
方法3:Thread(String name)
创建线程对象,并初始化线程的名字
方法4:Thread(Runnable r,String name)
使用Runnalbe对象创建线程,并初始化线程的名字
六,线程方法的使用
前台线程: 会阻止进程结束,如果前台线程没有执行完,进程是无法结束的.
后台进程: 不会阻止进程结束,即使后台线程没有执行完,进程也是可以结束的.
我们在main方法中创建的线程会默认为前台线程,但是我们可以使用setDaemon()方法去设置线程
public class ThreadDemo7 {public static void main(String[] args) {Thread t =new Thread(() -> {while (true) {System.out.println("我是后台线程");}});t.setDaemon(true); //设置该线程为后台线程t.start();System.out.println("我是前台线程");}
}
此处中断就是字面意思,就是让一个线程停下来!
public class ThreadDemo8 {private static boolean flag = true;public static void main(String[] args) throws InterruptedException {Thread t= new Thread(() -> {while(flag) {System.out.println("hello Thread");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}});t.start();Thread.sleep(3000);flag = false;}
}
interrupt方法的作用:
1.设置标志位为true
2.如果该线程正在阻塞中(比如在执行sleep),此时就把阻塞状态唤醒,通过抛异常的方式让sleep立即结束
public class ThreadDemo9 {public static void main(String[] args) throws InterruptedException {Thread t = new Thread(() -> {while(!Thread.currentThread().isInterrupted()) {System.out.println("hello Thread");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();//等待0.5s在进行终止try {Thread.sleep(500);} catch (InterruptedException ex) {e.printStackTrace();}break;}}});t.start();Thread.sleep(3000);t.interrupt();}
}
Thread类中有一个方法是Thread.currentThread().isIntercurrpted(),它的返回值默认为false
当外部调用t.interrupt()时 它的返回值会转变为true.
但是如果调用t.interript()方法时,t线程正处于休眠状态(sleep状态),会立即被唤醒,被唤醒之后sleep会报出异常,但是代码仍然会继续执行.
为什么代码会继续执行?
因为此时sleep会进行清除标志位的操作,也就是将修改为true的标志位,修改回false
那么,为什么sleep要进行清除标志位的操作呢?
因为当程序被唤醒后,它不清楚程序是否要进行中断操作,将这个问题抛给了程序员,此时线程是否中断,完全取决于程序员设计的代码.
比如上面的事例代码,我在里面加入了break操作,让循环终止,程序结束,那么线程也就随之销毁,是执行了中断操作;而我又在break前面加上了一个sleep,让其先休眠 0.5s 再进行中断操作,这就意味着,线程是否被中断,取决于其中代码的实现.
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线程调用t.join的时候,如果t还执行
此时main线程阻塞,再到t执行完毕(t的run执行完了),main才从阻塞中解除,才执行
2.main线程调用t.join的时候,如果t结束
此时join不会阻塞,会立即往下执行
都保证t是先结束的
join还有一个有参的版本,填写一个参数,作为超时时间,最大等待时间
如果等待时间到达上限,还没结束,就不等了
4. 线程休眠
线程的休眠和前面提到的sleep方法有关
当线程处于sleep状态时,就是处于休眠状态
public class Test {public static void main(String[] args) {Thread t = new Thread(() -> {while(true) {try {//sleep方法会让代码有执行间隔时间Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});t.start();}
}
5. 获取线程实例
Thread.currentThread()方法
它是一个类方法,作用是获取当前线程的实例
也就是说: 你在哪个线程中去调用这个方法,那么它就会返回这个线程的实例对象.
public class ThreadDemo11 {public static void main(String[] args) {Thread t = new Thread(() -> {System.out.println(Thread.currentThread().getName());},"t线程");t.start();}
}