|
|
|
@ -32,13 +32,13 @@ |
|
|
|
|
|
|
|
|
|
#### 一些 Object、Thread 方法的理解? |
|
|
|
|
|
|
|
|
|
首先就是线程的等待通知机制,等待通知机制设计到了两个函数 wait 和 notify/notifyAll,它们就是 Object 的方法,wait 函数是当一个线程调用了共享变量的 wait 方法时,该调用线程就会被阻塞挂起,直到其他线程调用了该共享变量的 notify/notifyAll 方法唤醒。需要注意的是,调用 wait 方法的线程需要先获取该对象的监视器锁,不然就会抛出 IllegalMonitorStateException,那么如何获取一个共享变量的监视器锁呢?其实就是加 synchronzied 即可。调用 wait 方法会释放当前共享变量的监视器锁,不然就会死锁了。wait 还有一个超时重载函数,如果在指定时间没有被唤醒就直接返回了,无参 wait 调用的其实就 wait(0) 方法。调用 notify 函数是随机唤醒一个等待线程,而 notifyAll 就是唤醒所有等待线程。同 wait 一致,只有获取了共享变量的监视器锁后,才可以调用其 notify/notifyAll 方法。 |
|
|
|
|
首先就是线程的等待通知机制,等待通知机制涉及到了两个函数 wait 和 notify/notifyAll,它们就是 Object 的方法,wait 函数是当一个线程调用了共享变量的 wait 方法时,该调用线程就会被阻塞挂起,直到其他线程调用了该共享变量的 notify/notifyAll 方法唤醒。需要注意的是,调用 wait 方法的线程需要先获取该对象的监视器锁,不然就会抛出 IllegalMonitorStateException,那么如何获取一个共享变量的监视器锁呢?其实就是加 synchronzied 即可。调用 wait 方法会释放当前共享变量的监视器锁,不然就会死锁了。wait 还有一个超时重载函数,如果在指定时间没有被唤醒就直接返回了,无参 wait 调用的其实就 wait(0) 方法。调用 notify 函数是随机唤醒一个等待线程,而 notifyAll 就是唤醒所有等待线程。同 wait 一致,只有获取了共享变量的监视器锁后,才可以调用其 notify/notifyAll 方法。 |
|
|
|
|
|
|
|
|
|
还有等待线程执行完成的 join 方法,以及让线程休眠的 sleep 方法,sleep 方法和 wait 方法不同的是,sleep 并不会释放锁。Object#wait、Thread#join、Thread#sleep 在阻塞期间,其他线程调用了该线程的 interrupt 方法中断线程,都会抛出 InterruptedException。 |
|
|
|
|
|
|
|
|
|
其次就是让出 CPU 执行权的 Thread#yield 方法,让线程调度器进行下一轮的线程调度,不过需要注意的是,下一轮调度的时候也有可能会再次调度到自己。yield 方法一般是用在自旋中。 |
|
|
|
|
|
|
|
|
|
最后就是线程中断了,线程中断是一种线程间的协作模式,通过设置线程的中断标志并不能直接中断线程的执行,而是被中断的线程根据中断状态自行处理。现在中断包括两个函数,一个 interrupt() 方法,中断线程,还有一个是 Thread 的静态方法 interrupted 方法,前者不会清楚标志位,后者会清除标志位。 |
|
|
|
|
最后就是线程中断了,线程中断是一种线程间的协作模式,通过设置线程的中断标志并不能直接中断线程的执行,而是被中断的线程根据中断状态自行处理。现在中断包括两个函数,一个 interrupt() 方法,中断线程,还有一个是 Thread 的静态方法 interrupted 方法,前者不会清除标志位,后者会清除标志位。 |
|
|
|
|
|
|
|
|
|
#### 线程死锁 |
|
|
|
|
|
|
|
|
@ -94,7 +94,7 @@ Lock 和 synchronized 相比,都是可重入的独占锁,不同的是 Lock |
|
|
|
|
|
|
|
|
|
原子类即是指 Java 中的 Atomic 类,比如 AtomicInteger、AtomicLong、AtomicStampedReference、AtomicReference 等。都是通过 CAS 来做的。 |
|
|
|
|
|
|
|
|
|
CAS 即比较并替换,它的通过硬件来保证操作的原子性。 |
|
|
|
|
CAS 即比较并替换,它是通过硬件来保证操作的原子性。 |
|
|
|
|
|
|
|
|
|
在 Java 中,UnSafe 类提供了对 CAS 的简单封装,Atomic 类内部也都是使用 UnSafe 类来做的,UnSafe 类是可以直接操作内存的,一般在应用程序中是不能使用的,它是由启动类加载器加载的。UnSafe 类提供了一系列的 compareAndSwapXxx 方法,它们都是 native 方法。除此之外,UnSafe 还有一对 park/unpark 阻塞唤醒线程的方法,LockSupport 便是对它的包装。 |
|
|
|
|
|
|
|
|
|