16、什么是并发容器的实现?
何为同步容器:可以简单地理解为通过 synchronized 来实现同步的容器,如果有 多个线程调用同步容器的方法,它们将会串行执行。比如 Vector,Hashtable, 以及 Collections.synchronizedSet,synchronizedList 等方法返回的容器。 可以通过查看 Vector,Hashtable 等这些同步容器的实现代码,可以看到这些容 器实现线程安全的方式就是将它们的状态封装起来,并在需要同步的方法上加上 关键字 synchronized。 并发容器使用了与同步容器完全不同的加锁策略来提供更高的并发性和伸缩性, 例如在 ConcurrentHashMap 中采用了一种粒度更细的加锁机制,可以称为分段 锁,在这种锁机制下,允许任意数量的读线程并发地访问 map,并且执行读操作 的线程和写操作的线程也可以并发的访问 map,同时允许一定数量的写操作线程 并发地修改 map,所以它可以在并发环境下实现更高的吞吐量。
17、多线程同步和互斥有几种实现方法,都是什么?
线程同步是指线程之间所具有的一种制约关系,一个线程的执行依赖另一个线程 的消息,当它没有得到另一个线程的消息时应等待,直到消息到达时才被唤醒。 线程互斥是指对于共享的进程系统资源,在各单个线程访问时的排它性。当有若 干个线程都要使用某一共享资源时,任何时刻最多只允许一个线程去使用,其它 要使用该资源的线程必须等待,直到占用资源者释放该资源。
线程互斥可以看成 是一种特殊的线程同步。 线程间的同步方法大体可分为两类:用户模式和内核模式。顾名思义,内核模式 就是指利用系统内核对象的单一性来进行同步,使用时需要切换内核态与用户态, 而用户模式就是不需要切换到内核态,只在用户态完成操作。 用户模式下的方法有:原子操作(例如一个单一的全局变量),临界区。内核模 式下的方法有:事件,信号量,互斥量。
18、什么是竞争条件?你怎样发现和解决竞争?
当多个进程都企图对共享数据进行某种处理,而最后的结果又取决于进程运行的 顺序时,则我们认为这发生了竞争条件(race condition)。
19、为什么我们调用 start()方法时会执行 run()方法,为什么我们不能直接调用 run()方法?
当你调用 start()方法时你将创建新的线程,并且执行在 run()方法里的代码。 但是如果你直接调用 run()方法,它不会创建新的线程也不会执行调用线程的代码, 只会把 run 方法当作普通方法去执行。
20、Java 中你怎样唤醒一个阻塞的线程?
在 Java 发展史上曾经使用 suspend()、resume()方法对于线程进行阻塞唤醒,但 随之出现很多问题,比较典型的还是死锁问题。 解决方案可以使用以对象为目标的阻塞,即利用 Object 类的 wait()和 notify()方 法实现线程阻塞。 首先,wait、notify 方法是针对对象的,调用任意对象的 wait()方法都将导致线程 阻塞,阻塞的同时也将释放该对象的锁,相应地,调用任意对象的 notify()方法则 将随机解除该对象阻塞的线程,但它需要重新获取改对象的锁,直到获取成功才 能往下执行;其次,wait、notify 方法必须在 synchronized 块或方法中被调用, 并且要保证同步块或方法的锁对象与调用 wait、notify 方法的对象是同一个,如 此一来在调用 wait 之前当前线程就已经成功获取某对象的锁,执行 wait 阻塞后当 前线程就将之前获取的对象锁释放。