Android:多线程总结

2018-07-31  本文已影响23人  我在等你回复可你没回

多线程总结

问题一:多线程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

上一篇下一篇

猜你喜欢

热点阅读