1.Thread.sleep(long millis),一定是当前线程调用此方法,当前线程进入TIMED_WAITING状态,但不释放对象锁,millis后线程自动苏醒进入就绪状态。作用:给其它线程执行机会的最佳方式。
2.Thread.yield(),一定是当前线程调用此方法,当前线程放弃获取的CPU时间片,但不释放锁资源,由运行状态变为就绪状态,让OS再次选择线程。作用:让相同优先级的线程轮流执行,但并不保证一定会轮流执行。实际中无法保证yield()达到让步目的,因为让步的线程还有可能被线程调度程序再次选中。Thread.yield()不会导致阻塞。该方法与sleep()类似,只是不能由用户指定暂停多长时间。
3.thread.join()/thread.join(long millis),当前线程里调用其它线程t的join方法,当前线程进入WAITING/TIMED_WAITING状态,它会释放thread实例的对象锁,但不会释放其它对象锁(包括main线程)。线程t执行完毕或者millis时间到。
解释如下:t2对象调用t1.join()实际上是将t1作为锁对象,调用t1.wait()方法,则此时t2会释放t1对象锁,同时t2进入waiting状态。而此时t1还是running状态。
@Slf4j(topic = "c.Test1")
public class Test2 {
public static void main(String [] args){
Thread t1 =new Thread(new Runnable() {
@Override
public void run() {
int a = 11;
//模拟t1线程运行代码
for (int i=0;i<1000000000;i++){
a = a+a%10;
}
}
},"t1");
Thread t2 =new Thread(new Runnable() {
@Override
public void run() {
try {
t1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"t1");
Thread t3 =new Thread(new Runnable() {
@Override
public void run() {
log.debug("t1的运行状态{}",t1.getState());
log.debug("t2的运行状态{}",t2.getState());
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
log.debug("t1的运行状态{}",t1.getState());
log.debug("t2的运行状态{}",t2.getState());
}
},"t1");
t1.start();
t2.start();
t3.start();
}
}
4.obj.wait(),当前线程调用某一个作为锁的对象的wait()方法,当前线程释放对象锁,进入等待队列。依靠notify()/notifyAll()唤醒或者wait(long timeout) timeout时间到自动唤醒。
5.obj.notify()唤醒在此对象监视器上等待的单个线程,选择是任意性的。notifyAll()唤醒在此对象监视器上等待的所有线程。
6.LockSupport.park() / LockSupport.parkNanos(long nanos),LockSupport.parkUntil(long deadlines), 当前线程进入WAITING/TIMED_WAITING状态。对比wait方法,不需要获得锁就可以让线程进入WAITING/TIMED_WAITING状态,需要通过LockSupport.unpark(Thread thread)唤醒。
参考(https://blog.csdn.net/pange1991/article/details/53860651)
仅供自己笔记使用,侵权删除。