创建方式
thread线程创建的三种方式_NokeNoke的博客-CSDN博客
线程的启动过程
Java线程 start()方法执行后,会向操作系统去请求创建一个线程返回给JVM,JVM接收到线程创建成功之后会等待操作系统调度,系统激活线程后执行任务
应用层:通过实现一个 Runnable接口,然后将接口的实例作为参数传递到JDK提供的Thread类中。
JDK层:通过JNI的方式来调用给JVM虚拟机。
线程调度模块:根据当前运行的操作系统来调用对应的系统线程触发接口来创建具体的线程进行执行
pthread_create线程接口:pthread_create是类Unix操作系统(Unix、Linux、Mac OS X等)的创建线程的函数。它的功能是创建线程(实际上就是确定调用该线程函数的入口点),在线程创建以后,就开始运行相关的线程函数。
线程状态转换:
java.lang.Thread.State枚举类定义了六种线程状态
NEW: 新建初始状态,例如new Thread(),并且没有调用start()方法;
RUNNABLE: 调用了start()方法,java线程中将操作系统中的就绪状态(ready)和运行中状态(running)统一归类为可运行状态(RUNNABLE),该状态的线程在jvm中是运行状态,但可能处于等待操作系统cpu的调度。
BLOCKED: 阻塞状态,线程阻塞于;触发条件见图
WAITING: 等待状态,进入该状态的线程需要等待其它线程进行一些特殊操作,如notify、notifyAll、unpark;触发条件见图
TIMED_WAITING: 超时等待状态,该状态与WAITING不同之处是在指定时间后可以自动唤醒到就绪状态;触发条件:见图
TERMINATED:终止
守护线程:
Java中有两类线程, User Thread(用户线程)、Daemon Thread(守护线程) ,只要当前JVM实例中尚存在任何一个非守护线程没有结束,守护线程就会工作,只有当最后一个非守护线程结束时,守护线程随着JVM一同结束工作,常见的垃圾回收就是守护线程。
常见api
- currentThread() Thread类的静态方法,获取当前线程对象
- setPriority() 为线程设定优先级 与yield方法一样,是一个非强制的方法,cpu很忙时,设置的优先级高的会获取更多的资源,闲的时候没什么区别
线程默认继承父类的优先级,默认5
1-10返回, 大于线程所在group的优先级,则为group的最大优先级
- getPriority() 获取线程优先级
- isAlive() thread实例方法,线程是否存活
- sleep() Thread类的静态方法,当前线程休眠
TimeUnit.SECONDS.sleep(1);
TimeUnit.MINUTES.sleep(1); 这个方法比sleep用起来更方便,和sleep完全一致
- getId()方法 thread实例方法 返回的是Thread静态 threadSeqNumber属性
- yield() 提醒调度器放弃 cpu资源,如果cpu不紧张,可能会忽略
- resume(),suspend() 暂停和恢复线程, 被resume()的线程会独占共享资源,不释放锁
- stop() 停止线程,导致清理的工作不完成,线程同步问题
- setDaemon() 设置守护线程
- join() join某个线程A,会使当前线程B进入等待,直到A结束生命周期,或者给定的时间
- interrupt() 中断方法,中断线程的阻塞状态,一旦线程在阻塞状态情况下被打断,都会抛出InterruptedException异常; 线程执行 interrupt flag默认=false, 执行isInterrupted()状态变为true,但是有几种例外,1.可中断方法被catch了,2.Thread. interrupted()执行 这两种情况会状态转为false
- interrupt(): 由其他线程调用,终止执行该方法的线程 的阻塞状态, interrupt flag,如果一个线程没有可中断方法,执行状态不受影响,但是isInterrupted()状态变为true,如果已经终止,interrupt()会直接被忽略,isInterrupted()状态也不会变
- isInterrupted(): 正常为false ,执行了interrupt()变为true,如果执行interrupt()后可中断方法InterruptedException被捕获,则interrupt flag 被擦除, isInterrupted()= false; isInterrupted()执行后不会影响interrupt flag 标识
- interrupted(): Public static boolean interrupted() = currentThread().isInterrupted(true),true:ClearInterrupted
public class InterruptTest {
public static void main(String[] args) throws InterruptedException {
testInterrupt();
testInterrupt2();
testInterrupt3();
testIsInterrupted();
testIsInterrupted2();
testIsInterrupted3();
testInterrupted();
}
// interrupt()
public static void testInterrupt() throws InterruptedException {
Thread thread = new Thread(() -> {
try {
TimeUnit.MINUTES.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
thread.start();
TimeUnit.MILLISECONDS.sleep(1);
thread.interrupt();
}
// interrupt()
public static void testInterrupt2() throws InterruptedException {
Thread thread = new Thread(() -> {
int i = 0;
while (true) {
System.out.println(i++);
}
});
thread.start();
TimeUnit.MILLISECONDS.sleep(10);
thread.interrupt();
TimeUnit.MINUTES.sleep(10);
}
/**
* interrupt() 在可中断方法前执行,可中断方法会立刻抛出InterruptedException
* Thread.interrupted() 擦除后,可中断方法不会InterruptedException
* InterruptedException 是否抛出是判断当前 Interrupted flag = true 就会执行
*/
public static void testInterrupt3() {
System.out.println(Thread.currentThread().isInterrupted());
Thread.currentThread().interrupt();
// System.out.println(Thread.interrupted());
try {
TimeUnit.SECONDS.sleep(1);
System.out.println("-----sleep-end------");
} catch (InterruptedException e) {
System.out.println("-----catch------");
}
}
// isInterrupted()
public static void testIsInterrupted() throws InterruptedException {
Thread thread = new Thread(() -> {
while (true) {
}
});
thread.start();
TimeUnit.MILLISECONDS.sleep(5);
System.out.println(thread.isInterrupted());
System.out.println(thread.isInterrupted());
thread.interrupt();
System.out.println(thread.isInterrupted());
}
// isInterrupted()
public static void testIsInterrupted2() throws InterruptedException {
Thread thread = new Thread(() -> {
try {
TimeUnit.MILLISECONDS.sleep(10);
System.out.println("thread---end------");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
thread.start();
TimeUnit.MILLISECONDS.sleep(20);
System.out.println(thread.isInterrupted());
thread.interrupt();
System.out.println(thread.isInterrupted());
}
/**
* catch 执行完后擦除interrupted标识,true->false
*
* @throws InterruptedException
*/
public static void testIsInterrupted3() throws InterruptedException {
Thread thread = new Thread(() -> {
try {
TimeUnit.MINUTES.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
thread.start();
TimeUnit.MILLISECONDS.sleep(10);
System.out.println("flag1=" + thread.isInterrupted());
thread.interrupt();
System.out.println("flag2=" + thread.isInterrupted());
}
// static interrupted()
public static void testInterrupted() throws InterruptedException {
Thread thread = new Thread(() -> {
while (true) {
System.out.println(Thread.interrupted());
}
});
thread.setDaemon(true);
thread.start();
TimeUnit.MILLISECONDS.sleep(10);
thread.interrupt();
}
其他
- sleep与wait的区别
sleep( ) 和 wait( ) 的区别_NokeNoke的博客-CSDN博客
- 下面代码块结果的理解,run方法中一个 是"A",一个是"Thread-0",因为 thread.start()并不会调用countPoerate.start()方法,所以执行run方法的线程实际是thread而非countPoerate,所以Thread.currentThread().getName()= "A", 但是thread.run()方法执行的时候,使用的target对象是构造函数中传递的countPoerate,所以this.getName()="Thread-0", CountPoerate countPoerate = new CountPoerate()的作用是提供了一个对象的实例方法而非一个线程
public class CountPoerate extends Thread {
public CountPoerate() {
System.out.println("CountPoerate--begin");
System.out.println("Thread.currentThread().getName()=" + Thread.currentThread().getName());
System.out.println("this.getName()=" + this.getName());
System.out.println("CountPoerate--end");
}
@Override
public void run() {
System.out.println("run--begin");
System.out.println("Thread.currentThread().getName()=" + Thread.currentThread().getName());
System.out.println("this.getName()=" + this.getName());
System.out.println("run--end");
}
public static void main(String[] args) {
CountPoerate countPoerate = new CountPoerate();
Thread thread = new Thread(countPoerate);
thread.setName("A");
thread.start();
}
}