1.start与run的区别
@Slf4j(topic = "c.TestStartAndRun")
public class TestStartAndRun {
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 ...");
}
}
改为start后
区别1.直接调用 run 是在主线程中执行了 run,没有启动新的线程
2.使用 start 是启动新的线程,通过新的线程间接执行 run 中的代码
start只能调用一次,run可以调用多次。
2. sleep 与 yield
sleep
1. 调用 sleep 会让当前线程从 Running 进入 Timed Waiting 状态(阻塞)
public class Test6 {
public static void main(String[] args) {
Thread t1 = new Thread("t1") {
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
t1.start();
log.debug("t1 state: {}", t1.getState());
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
log.debug("t1 state: {}", t1.getState());
}
}
t1一开始是runnable应该是主线程先运行了。
2. 其它线程可以使用 interrupt 方法打断正在睡眠的线程,这时 sleep 方法会抛出 InterruptedException
@Slf4j(topic = "c.Test7")
public class Test7 {
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("enter sleep...");
e.printStackTrace();
}
}
};
t1.start();
Thread.sleep(1000);
log.debug("interrupt...");
t1.interrupt();
}
}
3. 睡眠结束后的线程未必会立刻得到执行
yield
1. 调用 yield 会让当前线程从 Running 进入 Runnable 就绪状态,然后调度执行其它线程
2. 具体的实现依赖于操作系统的任务调度器 (如果没有其他等待的线程即使让出去CPU也会重新分配给当前线程)。
3. join方法详解
@Slf4j(topic = "c.Test10")
public class Test10 {
static int r = 0;
private static void test1() throws InterruptedException {
log.debug("开始");
Thread t1 = new Thread(() -> {
log.debug("开始");
sleep(1);
log.debug("结束");
r = 10;
}, "t1");
t1.start();
//t1.join();
log.debug("结果为:{}", r);
log.debug("结束");
}
public static void main(String[] args) throws InterruptedException {
test1();
}
}
t1.join注释去掉后
等t1线程结束后才会运行主线程。
join的作用:等待调用它的线程运行结束
4. interrupt详解
@Slf4j(topic = "c.Test11")
public class Test11 {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
log.debug("sleep...");
try {
Thread.sleep(5000); // wait, join
} catch (InterruptedException e) {
e.printStackTrace();
}
},"t1");
t1.start();
Thread.sleep(500);
log.debug("interrupt");
t1.interrupt();
log.debug("打断标记:{}", t1.isInterrupted());
}
}
打断 sleep 的线程, 会清空打断状态,以 sleep 为例
@Slf4j(topic = "c.Test12")
public class Test12 {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
while(true) {
boolean interrupted = Thread.currentThread().isInterrupted();
if(interrupted) {
log.debug("被打断了, 退出循环");
break;
}
}
}, "t1");
t1.start();
Thread.sleep(1000);
log.debug("interrupt");
t1.interrupt();
log.debug("打断标记:{}", t1.isInterrupted());
}
}
这种打断正常运行的线程, 不会清空打断状态
5. 不推荐的方法
还有一些不推荐使用的方法,这些方法已过时,容易破坏同步代码块,造成线程死锁
stop() 停止线程运行
suspend() 挂起(暂停)线程运行
resume() 恢复线程运行