Java认证考试实例疑难辨析(3)

来源:互联网 发布:淘宝页尾1920全屏代码 编辑:程序博客网 时间:2024/05/23 00:01

3.

【知识点】

(1)线程同步(Thread Synchronization)

线程间通信主要是通过共享字段(Field)或对象引用实现的,这种通信形式虽然高效,但会带来线程干扰(Thread Interference)和内存不一致的弊端,线程同步机制就是防止这类弊端的机制。不过,线程同步机制又会带来线程竞争(Thread Contention)问题,即在两个或两个以上线程同时访问同一资源时导致线程阻塞。

(2)内部锁(Intrinsic Lock),又称监控锁(Monitor Lock)

Java同步化机制是围绕内部锁建立的,每个对象都拥有唯一的一把内部锁,当线程需要排他性地访问某个对象时,这个线程就需要拥有那个对象的内部锁,一旦这个线程拥有那个对象的内部锁,其他线程就不能再获得那把内部锁,如果其他线程仍试图去获取那把内部锁将会被阻塞。

(3)同步化方法(Synchronized Method)和同步化语句(Synchronized Statement)

Java语言为同步化机制提供了两种基本形式,即同步化方法(Synchronized Method)和同步化语句(Synchronized Statement)。synchronized是建立同步化方法或语句的关键词。

当一个线程执行一个同步化方法时,线程就默认拥有同步化方法所在对象的内部锁,其他线程要调用这个对象的同步化方法(即使是不同的同步化方法)时都会被阻塞,直到第一个线程执行完成同步化方法释放内部锁后才能再执行这个对象的同步化方法。

同步化语句则是更加灵活的同步化机制,通过synchronized关键词明确指定提供内部锁的对象,这样同一个对象中不同的同步化语句块就可以拥有不同的内部锁,不同的同步化语句块就可以让不同的线程调用执行。

(4)wait()、notify()、notifyAll()方法

调用这几个方法的对象的内部锁必须被当前线程获得,如果当前线程不是主调对象内部锁的拥有者,则会抛出IllegalMonitorStateException。

让调用这几个方法的线程拥有主调对象内部锁的方式,主要有:

(a)执行主调对象中同步化实例方法;

(b)执行主调对象同步化语句块;

(c)对于Class对象,执行它的同步化静态方法。

【例题】

Given:
       void waitForSignal(){

              Object obj = new Object();

              synchronized (Thread.currentThread()) {

                     obj.wait();

                     obj.notify();

              }

       }

Which statement is true?

A. This code can throw anInterruptedException.

B. This code can throw anIllegalMonitorStateException.

C. This code can throw aTimeoutException after ten minutes.

D. Reversing the order ofobj.wait() and obj.notify() might cause this method to complete normally.

E. A call to notify() ornotifyAll() from another thread might cause this method to complete normally.

F. This code does NOT compileunless "obj.wait()" is replaced with "((Thread)obj).wait()".

【Answer】 B

 

【例题辨析】

(1)wait()和notify()这两个方法都会抛出IllegalMonitorStateException,这个异常是RuntimeException的子类,属于unchecked exception,可以不捕捉。但是,wait()方法还会抛出InterruptedException,这个异常必须捕捉,因此程序有编译错误。应该为waitForSignal方法声明中添加throws InterruptedException:

void waitForSignal() throws InterruptedException {

……

或者,为wait()和notify()方法调用语句添加try…catch…

(2)本例中,wait()和notify()方法的主调对象是obj,而obj对象的内部锁没有被当前线程取得,不符合wait()、notify()方法的调用条件,因此调用waitForSignal()时,会抛出如下异常:

Exception in thread "main"java.lang.IllegalMonitorStateException

       atjava.lang.Object.wait(Native Method)

       atjava.lang.Object.wait(Unknown Source)

       atExamA_3.waitForSignal(ExamA_3.java:6)

       atExamA_3.main(ExamA_3.java:13)

解决方案是将synchronized (Thread.currentThread())修改为synchronized (obj),这样当前线程就取得了obj对象的内部锁。

A. InterruptedException在编译时就会发现,因此不会在运行时抛出;

B. 根据上面分析可知正确;

C. 线程死锁是无法预知时间的;

D. 本程序错误不在于obj.wait() and obj.notify()调用顺序,而是在于当前线程没有取得obj内部锁;

E. 同上

F. 同上
0 0
原创粉丝点击