方法 | 说明 |
---|---|
Thread() | 默认无参构造方法 |
Thread(Runnable target) | 使用Runnable对象创建线程对象 |
Thread(String name) | 创建线程对象,并给线程起名字 |
Thread(Runnable target,String name) | 使用Runnable对象创建线程对象,并给线程起名字 |
给线程起名字
public class demo1 {public static void main(String[] args) {Thread t = new Thread(() -> {while(true){System.out.println("Thread");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}},"线程一");t.start();while (true){System.out.println("main");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}
}
属性 | 方法 |
---|---|
ID | getId() |
名称 | getName() |
状态 | getState() |
优先级 | getPriority() |
是否后台线程 | isDaemon() |
是否存活 | isAlive() |
是否被中断 | isInterrupted() |
说明
getId()
ID是线程唯一标识,不同线程不会重复
getName()
线程的名称
getState()
表示线程当前所处的一个情况
getPriority()
获得线程的优先级
isDaemon()
JVM会在一个进程的所有非后台线程结束后,才会结束运行,这里的后台,和我们常说的手机后台应用类似线程创建的时候,默认是一个前台线程,前台线程可以阻止进程的退出,后台线程不影响进程的退出
public class Demo5 {public static void main(String[] args) {Thread thread = new Thread(() -> {while (true) {System.out.println("thread...");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}});thread.start();} }
由于线程是前台进程,需要等待运行结束,进程才结束。代码为死循环,所以将会一直执行。
利用
setDaemom()
方法将线程设置为后台进程,等主线程执行完,进程就结束了,注意:先设置后台进程,再启动线程public class Demo5 {public static void main(String[] args) {Thread thread = new Thread(() -> {while (true) {System.out.println("thread...");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}});thread.setDaemon(true);thread.start();System.out.println("main.....");} }
创建Thread
对象、重写run
方法,只是给线程安排了任务,并没有执行,而调用start
方法,才是创建出了线程
**线程结束其实就是让线程的入口方法执行完 **
而中断线程,其实就是让线程停止下来,结束入口方法的执行
有2种方法可以中断线程
**方法一:直接用自定义的变量来作为标志位 **
需要给标志位上加
volatile
关键字这里我们以李四在银行取钱为例
public class Demo8 {private static class MyRunnable implements Runnable {public volatile boolean isQuit = false;@Overridepublic void run() {while (!isQuit) {System.out.println(Thread.currentThread().getName()+ ": 别管我,我忙着转账呢!");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}System.out.println(Thread.currentThread().getName()+ ": 啊!险些误了大事");}}public static void main(String[] args) throws InterruptedException {MyRunnable target = new MyRunnable();Thread thread = new Thread(target, "李四");System.out.println(Thread.currentThread().getName()+ ": 让李四开始转账。");thread.start();Thread.sleep(5 * 1000);System.out.println(Thread.currentThread().getName()+ ": 老板来电话了,得赶紧通知李四对方是个骗子!");target.isQuit = true;} }
方法二:使用
Thread
自带的标志位
Thread.interrupted()
或者Thread.currenThread().isInterrupted()
public class Demo9 {private static class MyRunnable implements Runnable {@Overridepublic void run() {while (!Thread.currentThread().isInterrupted()) {System.out.println(Thread.currentThread().getName()+ ": 别管我,我忙着转账呢!");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}System.out.println(Thread.currentThread().getName()+ ": 啊!险些误了大事");}}public static void main(String[] args) throws InterruptedException {MyRunnable target = new MyRunnable();Thread thread = new Thread(target, "李四");System.out.println(Thread.currentThread().getName()+ ": 让李四开始转账。");thread.start();Thread.sleep(5 * 1000);System.out.println(Thread.currentThread().getName()+ ": 老板来电话了,得赶紧通知李四对方是个骗子!");thread.interrupt();} }
运行结果
这时抛出了
InterruptedException
异常这是为什么呢?
由于线程的有效任务是打印一句话,这个操作耗时比较小,大部分时间线程都在
sleep
状态,正常来说,当线程在运行真正有效任务时去中断才是一个有效的中断,而在线程休眠的时候中断,其实是把休眠给中断了,而休眠本身没有到指定的时间,所以抛出了InterruptedException
异常当我们去掉线程中的休眠时,结果如下
这时候线程才真正的中断了
我们知道线程之间的执行顺序是根据系统调度随机执行的,但有时我们需要等待一个线程执行完,再执行下一个线程,这时我们需要一个方法明确等待线程结束,
public class Demo10 {public static void main(String[] args) throws InterruptedException {Runnable target = () -> {for (int i = 0; i < 3; i++) {System.out.println(Thread.currentThread().getName() + ":正在工作!");try {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("王五结束了工作");} }
join()其他方法
public void join() | 等待线程结束(一直等,知道线程执行的任务结束) |
---|---|
public void join(long millis) | 等待线程结束,但等待millis毫秒 |
public void join(long millis, int nanos) | 同理 |
private static Thread currentThread()
返回当前线程对象的引用
让线程休眠休眠一会
图解sleep()的具体使用
在Java线程分为6种状态
1. NEW:创建好了一个Java的Thread对象,并安排好了任务,没有调用start()方法之前,和PCB没有关系
2. RUNNABLE:运行+就绪状态,在执行任务时的一个常态之一
3. TIMED_WAITING:指定了一个时间的阻塞队列,过时不候
4. WAITING :没有指定时间的等待,一直死等
5. BLOCK:等待锁的状态
6. TERMINATED :结束,完成状态,PCB已经被销毁了,但是Java对象还在
查看线程状态
public class Demo14 {public static void main(String[] args) throws InterruptedException {Thread thread=new Thread(()->{for (int i = 0; i < 5; i++) {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});System.out.println("线程创建之前:"+thread.getState());thread.start();Thread.sleep(1000);System.out.println("启动线程,创建好PCB后:"+thread.getState());thread.join();System.out.println("线程执行完成后:"+thread.getState());} }
线程之间相互转换
觉得不错就留下你的三连吧