多线程总结
问题一:多线程join如何实现?
join用来等待一个线程完成。
join方法会调用wait函数,这个wait会在线程destory的时候被notify。
wait方法:
public final void join(long millis) throws InterruptedException {
synchronized(lock) {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (isAlive()) {
lock.wait(0); //或者就一直在等
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
lock.wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
}
线程destroy的时候notifyall
void Thread::Destroy() {
.....
// Thread.join() is implemented as an Object.wait() on the Thread.lock object. Signal anyone
// who is waiting.
ObjPtr<mirror::Object> lock =
jni::DecodeArtField(WellKnownClasses::java_lang_Thread_lock)->GetObject(tlsPtr_.opeer); //或者java属性
// (This conditional is only needed for tests, where Thread.lock won't have been set.)
if (lock != nullptr) {
StackHandleScope<1> hs(self);
Handle<mirror::Object> h_obj(hs.NewHandle(lock));
ObjectLock<mirror::Object> locker(self, h_obj);
locker.NotifyAll(); //线程destroy的时候notifyall
}
tlsPtr_.opeer = nullptr;
}
.....
}
问题二:notify和notifyAll有什么区别?
notify是唤起一个wait的线程,notifyAll是唤起所有wait的线程。notify可能导致死锁。
可参看:
https://www.zhihu.com/question/37601861
问题三:生产者和消费者模式如何实现?
使用wait和notify实现。
消费者:
while(true) {
Syncronize(queue) {
while(queue.size == 0) { //没有货物了,就等。要用while,因为害怕被错误唤醒
queue.wait();
}
queue.delete();
queue.notifyAll(); //唤起生产者,然后消费者和生产者一起去竞争锁。
}
}
生产者:
while(true) {
Syncronize(queue) {
while(queue.size == max) { //货物满了,就等
queue.wait();
}
queue.add();
queue.notifyAll();
}
}
问题三:同一个线程可以多次执行synchronized吗?
下面的程序会打出什么呢?
public static void main(String[]agrs)
{
synchronized (lock) {
System.out.println("first");
synchronized (lock) {
System.out.println("second");
}
}
}
答案是:
first
second
原因是synchronized是可重入的。取得锁之后,可以再次取得锁。每个锁关联一个线程持有者和一个计数器。再次取得锁时,计数器会加1.
ArrayBlockingQueue和LinkedBlockingQueue的区别
ArrayBlockingQueue长度固定。LinkedBlockingQueue长度不定。
ArrayBlockingQueue只用了一把锁,而LinkedBlockingQueue用了两把锁。
CopyOnWriteArrayList使用过吗?
使用的是写时复制的技术,占用内存大。但读取不用加锁,适合于经常读和不需要经常写的场景。
参考:http://www.cnblogs.com/dolphin0520/p/3938914.html
网友评论