线程中的常见方法
一、线程的常见方法
方法名 | static | 功能说明 | 注意 |
---|---|---|---|
start() | 启动一个新线 程,在新的线程 运行 run 方法 中的代码 |
start 方法只是让线程进入就绪,里面代码不一定立刻 运行(CPU 的时间片还没分给它)。每个线程对象的 start方法只能调用一次,如果调用了多次会出现 IllegalThreadStateException |
|
run() | 新线程启动后会 调用的方法 |
如果在构造 Thread 对象时传递了 Runnable 参数,则 线程启动后会调用 Runnable 中的 run 方法,否则默 认不执行任何操作。但可以创建 Thread 的子类对象, 来覆盖默认行为 |
|
join() | 等待线程运行结 束 |
||
join(long n) | 等待线程运行结 束,最多等待 n 毫秒 |
||
getId() | 获取线程长整型 的 id |
id 唯一 | |
getName() | 获取线程名 | ||
setName(String) | 修改线程名 | ||
getPriority() | 获取线程优先级 | ||
setPriority(int) | 修改线程优先级 | java中规定线程优先级是1~10 的整数,较大的优先级 能提高该线程被 CPU 调度的机率 |
|
getState() | 获取线程状态 | Java 中线程状态是用 6 个 enum 表示,分别为: NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED |
|
isInterrupted() | 判断是否被打 断, |
不会清除打断标记 |
|
isAlive() | 线程是否存活 (还没有运行完 毕) |
||
interrupt() | 打断线程 | 如果被打断线程正在 sleep,wait,join 会导致被打断 的线程抛出 InterruptedException,并清除 打断标 记 ;如果打断的正在运行的线程,则会设置打断标 记 ;park 的线程被打断,也会设置打断标记 |
|
interrupted() | static | 判断当前线程是 否被打断 |
会清除打断标记 |
currentThread() | static | 获取当前正在执 行的线程 |
|
sleep(long n) | static | 让当前执行的线 程休眠n毫秒, 休眠时让出 cpu 的时间片给其它 线程 |
|
yield() | static | 提示线程调度器 让出当前线程对 CPU的使用 |
主要是为了测试和调试 |
二、start 与 run
调用run
public static void main(String[] args) {
Thread t1 = new Thread("t1") {
@Override
public void run() {
log.debug(Thread.currentThread().getName());
FileReader.read(Constants.MP4_FULL_PATH);
}
};
t1.run();
log.debug("do other things ...");
}
输出:
19:39:14 [main] c.TestStart - main
19:39:14 [main] c.FileReader - read [1.mp4] start ...
19:39:18 [main] c.FileReader - read [1.mp4] end ... cost: 4227 ms
19:39:18 [main] c.TestStart - do other things ...
程序仍在 main 线程运行, FileReader.read()
方法调用还是同步的
调用start
将上述代码的t1.run()
改为
t1.start();
输出:
19:41:30 [main] c.TestStart - do other things ...
19:41:30 [t1] c.TestStart - t1
19:41:30 [t1] c.FileReader - read [1.mp4] start ...
19:41:35 [t1] c.FileReader - read [1.mp4] end ... cost: 4542 ms
程序在 t1 线程运行, FileReader.read()
方法调用是异步的
小结:
- 直接调用 run 是在主线程中执行了 run,没有启动新的线程
- 使用 start 是启动新的线程,通过新的线程间接执行 run 中的代码
三、sleep 与 yield
sleep
- 调用 sleep 会让当前线程从 Running 进入 Timed Waiting 状态(阻塞)
- 其它线程可以使用 interrupt 方法打断正在睡眠的线程,这时 sleep 方法会抛出 InterruptedException
- 睡眠结束后的线程未必会立刻得到执行
- 建议用 TimeUnit 的 sleep 代替 Thread 的 sleep 来获得更好的可读性
sleep_打断:interrupt()
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread("t1") {
@Override
public void run() {
log.debug("enter sleep...");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
log.debug("wake up...");
e.printStackTrace();
}
}
};
t1.start();
Thread.sleep(1000);
log.debug("interrupt...");
t1.interrupt();
}
12:26:16.749 c.Test7 [t1] - enter sleep...
12:26:17.746 c.Test7 [main] - interrupt...
12:26:17.746 c.Test7 [t1] - wake up...
java.lang.InterruptedException: sleep interrupted
sleep_可读性:
//两者效果一样,只不过第一个进行了单位换算,可读性更好
TimeUnit.SECONDS.sleep(1);
Thread.sleep(1000);
yield
- 调用 yield 会让当前线程从 Running 进入 Runnable 就绪状态,然后调度执行其它线程
- 具体的实现依赖于操作系统的任务调度器