package threading;
public class Demo7{
public static void main(String[] args) {
Thread t = new Thread(()->{
while(true){
System.out.println("hello");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
},"这是我的线程");
t.start();
}
}
这是一段用lambda表达式创建的线程。
Thread类的属性
1、ID( getId() )
这是Java中给Thread对象安排的身份标识。和操作系统内核的PCB的pid以及操作系统提供的线程API中的线程id都不是一回事!
一个线程:
1、JVM中有id
2、操作系统的线程API中有id
3、内核PCB中有id
2、名称( getName() )
在上面用lambda表达式创建的线程中我们能看到,
这个线程我指定name是“这是我的线程”。这一点,在jdk中的jconsole.exe中可以看到
3、状态( getState() )
操作系统中,状态有两种:就绪和阻塞。而在java中自己有一套状态:
NEW(初始): Thread 对象创建出来了,但是内核的 PCB 还没创建,(还没有真正创建线程)
TERMINATED(超时等待): 内核的 PCB 销毁了,但是 Thread 对象还在
RUNNABLE(运行):就绪状态(正在CPU上运行+在就绪队列中排队)
TIMED WAITING(超时等待): 按照一定的时间,进行阻塞.sleep
WAITING(等待): 特殊的阻塞状态. 调用 wait
BLOCKED(阻塞):等待锁的时候进入的阻塞状态
4、优先级( getPriority() )
5、是否为后台线程( isDaemon() )
我们默认创建的线程是前台线程。前台线程会阻止进程退出。所以,如果main运行完了,下前台线程还没完,进程就不会退出!
如果是后台线程就不会阻止进程的退出。
所以,如果main等其他前台线程执行完了,就算有后台线程没执行完,进程也会退出。
package threading;
public class Demo7{
public static void main(String[] args) {
Thread t = new Thread(()->{
while(true){
System.out.println("hello");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
},"这是我的线程");
//设置操作得在start之前。如果线程启动了,改不了
t.setDaemon(true);
t.start();
System.out.println("main线程执行结束。");
}
}
可以看到hello执行了一次就结束了。
6、是否存活( isAlive() )
线程是否存活 isAlive ——判定内核的线程在不在!
Thread 对象虽然和内核中的中的线程,是一一对应的关系, 但是生命周期并非完全相同。
Thread 对象出来了,内核里的线程还不一定有.调用 start 方法,内核线程才有!
当内核里的线程执行完了(run 运行完了),内核的线程就销毁了.但是 Thread 对象还在。
7、是否被中断( isInterrupted() )
线程的中断实际上是快点将线程结束。而不是运行一半中断。
中断的方法:用标准库里的标志位作为线程是否结束的标记来中断。
package threading;
public class Demo11 {
public static void main(String[] args) {
Thread t = new Thread(()->{
while (!Thread.currentThread().isInterrupted()){
System.out.println("hello thread");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("线程执行完了");
});
t.start();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
t.interrupt();
System.out.println("设置t线程结束");
}
}
Thread.currentThread().isInterrupted()
currentThread()是Thread的静态方法。通过这个方法可以拿到当前线程的实例(Thread对象)
isInterrupted就是判定标志位(为true)
运行3秒后会发现程序跳出异常后又正常运行。这是因为interrupt有两种情况:
1、t线程在运行状态
会设置标志位为true。
2、t线程在阻塞状态
不会设置标志位,而是触发InterruptedException
这个异常会提前唤醒sleep。
在上段代码中,异常的处理只是打印日志,且没有结束循环,所以线程会一直执行。
加上bread即可结束循环。
到这,我们能总结出:
在Java中,中断线程不是强制的。你可以自己处理如何中断线程。
立即结束:break;
不理会,线程继续执行:啥都不写
线程稍后处理:Thread.sleep(1000); break;