Java Monitor 的工作机理
- 想要获取monitor的线程,首先会进入_EntryList队列。
- 当某个线程获取到对象的monitor后,进入Owner区域,设置为当前线程,同时计数器count加1。
- 如果线程调用了wait()方法,则会进入WaitSet队列。它会释放monitor锁,即将owner赋值为null,count自减1,进入WaitSet队列阻塞等待。
- 如果其他线程调用 notify() / notifyAll() ,会唤醒WaitSet中的某个线程,该线程再次尝试获取monitor锁,成功即进入Owner区域。
- 同步方法执行完毕了,线程退出临界区,会将monitor的owner设为null,并释放监视锁。
Java的线程池执行原理
线程池的执行原理如下:
为了形象描述线程池执行,打个比喻:
- 核心线程比作公司正式员工
- 非核心线程比作外包员工
- 阻塞队列比作需求池
- 提交任务比作提需求
38 Java中用到的线程调度算法是什么?
我们知道有两种调度模型:分时调度和抢占式调度。
- 分时调度模型:让所有的线程轮流获得cpu的使用权,并且平均分配每个线程占用的 CPU 的时间片。
- 抢占式调度:优先让可运行池中优先级高的线程占用CPU,如果可运行池中的线程优先级相同,那么就随机选择一个线程,使其占用CPU。处于运行状态的线程会一直运行,直至它不得不放弃 CPU。
Java默认的线程调度算法是抢占式。即线程用完CPU之后,操作系统会根据线程优先级、线程饥饿情况等数据算出一个总的优先级并分配下一个时间片给某个线程执行。
java中interrupt(),interrupted()和isInterrupted()的区别
interrupt
它是真正触发中断的方法。interrupted
是Thread中的一个类方法,它也调用了isInterrupted(true)方法,不过它传递的参数是true,表示将会清除中断标志位。isInterrupted
是Thread
类中的一个实例方法,可以判断实例线程是否被中断。。
public void interrupt() {
if (this != Thread.currentThread())
checkAccess();
synchronized (blockerLock) {
Interruptible b = blocker;
if (b != null) {
interrupt0(); // Just to set the interrupt flag
b.interrupt(this);
return;
}
}
interrupt0();
}
public static boolean interrupted() {
return currentThread().isInterrupted(true);
}
public boolean isInterrupted() {
return isInterrupted(false);
}
Java中ConcurrentHashMap的并发度是什么?
并发度就是segment
的个数,通常是2的N次方。默认是16
Java线程有哪些常用的调度方法?
1 线程休眠
Thread.sleep(long)
方法,使线程转到超时等待阻塞(TIMED_WAITING) 状态。long
参数设定睡眠的时间,以毫秒为单位。当睡眠结束后,线程自动转为就绪(Runnable)
状态。
46.2 线程中断
interrupt()
表示中断线程。需要注意的是,InterruptedException
是线程自己从内部抛出的,并不是interrupt()
方法抛出的。对某一线程调用interrupt()
时,如果该线程正在执行普通的代码,那么该线程根本就不会抛出InterruptedException
。但是,一旦该线程进入到wait()/sleep()/join()
后,就会立刻抛出InterruptedException。可以用isInterrupted()
来获取状态。
46.3 线程等待
Object
类中的wait()
方法,会导致当前的线程等待,直到其他线程调用此对象的notify()
方法或notifyAll()
唤醒方法。
46.4 线程让步
Thread.yield()
方法,暂停当前正在执行的线程对象,把执行机会让给相同或者更高优先级的线程。
46.5 线程通知
Object的notify()
方法,唤醒在此对象监视器上等待的单个线程。如果所有线程都在此对象上等待,则会选择唤醒其中一个线程。选择是任意性的,并在对实现做出决定时发生。
notifyAll()
,则是唤醒在此对象监视器上等待的所有线程。