Java 的 sleep 和 wait 的区别
-
Sleep 是 Thread 的静态方法,wait 是 Object 的方法,任何对象都可以调用;
-
sleep 不会释放锁,它也不需要占用锁。Wait 会释放锁,但调用它的前提是当前线程占有锁;
-
他们都可以被 interrupted 方法打断。
怎么让一个线程等待另一个线程?
-
可以使用 wait 礼让
-
join等待其它线程终止
Sleep 是 Thread 的静态方法,wait 是 Object 的方法,任何对象都可以调用;
sleep 不会释放锁,它也不需要占用锁。Wait 会释放锁,但调用它的前提是当前线程占有锁;
他们都可以被 interrupted 方法打断。
可以使用 wait 礼让
join等待其它线程终止
start() 方法是用来启动线程,真正实现多线程运行。当调用 start() 方法后线程将从 NEW(新建)状态
变为 READY(就绪)状态
。只有当线程成为 READY(就绪)状态
时,他才可能得到 CPU 的调度,执行线程任务,也就是线程从 READY(就绪)状态
到 RUNABLE(执行)状态
的转换。 start() 方法是启动线程,但不是立即执行线程。
自旋锁原理很简单,如果持有锁的线程能在很短时间内释放锁资源,那么那些等待竞争锁的线程不需要在用户态与内核态之间切换,它们只需要等一等(自旋),等持有锁的线程释放锁后即可立即获取锁,这样就避免用户线程在用户态与内核态之间的切换开销。
线程自旋是需要消耗 CPU 的,原因就是自旋;当线程获取不到锁时,线程会持续主动访问资源锁,这样就会导致 CPU 做了很多无用功,所以使用自旋锁时,需要设定一个自旋等待最大时间,防止线程长时间自旋消耗 CPU 资源。
如果持有锁的线程执行的时间超过了自旋等待的最大时间仍然没有释放锁,就会导致其它竞争锁的线程停止自旋进入线程阻塞状态。
当线程执行 run()
方法结束后,线程就自动结束了。
public class ThreadOverDemo {
public static void main(String[] args) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
// 线程执行内容
}
});
thread.start();
}
}
线程池做的工作主要是控制运行的线程的数量,处理过程中将任务放入队列,然后在线程创建后启动这些任务,
如果线程数量超过了线程池的最大容量,那么超出数量的线程将会进行排队等待,等待其它线程执行完毕,再从
任务队列中取出任务来执行。它的主要特定是:线程服用、控制最大并发数和管理线程
。
每一个 Thread 的类都有一个 start 方法。当调用 start 启动线程时 Java 虚拟机会调用该类的 run 方法。那么
该类的 run() 方法中就是调用 Runnable 对象的 run() 方法。如果继承重写 Thread 类,在其 start 方法中添加不断循环调用传递过来的 Runnable 对象
。
这就是线程池的实现原理,循环方法中不断获取 Runnable 是用 Queue 实现的
,在获取下一个 Runnable 之前可以是阻塞的。