4.
【知识点】
(1)同步化方法(Synchronized Method)
同步化方法是Java实现同步化机制的两种基本形式之一,只要将synchronized关键词加入方法声明中就可以让方法成为同步化方法。
同步化方法的特点是同一对象中的同步化方法不允许同时被不同线程调用,即使是不同的同步化方法也不允许同时调用,也就是说,如果有一个线程调用了某个对象中的同步化方法,那么其他线程就不能同时调用这个对象中的所有同步化方法,因为每个对象只有一个内部锁,任何线程要调用同步化方法,必须拥有这个对象内部锁。
线程调用的同步化方法运行结束时,内部锁会自动归还方法所属的对象,其他线程就可以取得内部锁,然后调用该对象的同步化方法。
同步化方法可以确保对象状态改变对所有线程都是统一可见的,避免了多个线程调用同一对象中方法造成对象中字段值等状态信息的不一致。
【例题】
Given:
class PingPong2 {
synchronizedvoid hit(long n) {
for(int i= 1; i < 3; i++)
System.out.print(n+ "-" + i + " ");
}
}
public class Tester implements Runnable {
staticPingPong2 pp2 = new PingPong2();
publicstatic void main(String[] args) {
newThread(new Tester()).start();
newThread(new Tester()).start();
}
publicvoid run() { pp2.hit(Thread.currentThread().getId()); }
}
Which statement is true?
A. The output could be 5-1 6-1 6-2 5-2
B. The output could be 6-1 6-2 5-1 5-2
C. The output could be 6-1 5-2 6-2 5-1
D. The output could be 6-1 6-2 5-1 7-1
【Answer】 B
【例题辨析】
(1)主类Tester实现了线程方法run(),run()的主要工作就是取得当前线程号,main()方法创建了两个Tester类的线程对象,既然有两个线程对象,也就意味着run()代码在内存映像中有两份,即这两个run()方法是各自独立运行在两个不同线程中,因此,Thread.currentThread().getId()取得的是各自的线程号;
(2)线程号取得后作为参数传递给PingPong2类对象pp2的hit()方法,hit()方法负责显示输出信息,hit()是同步化方法,也就意味着当某个线程调用它时,另外的线程必须等待它运行结束,才能取得调用hit()的资格。
A. 从输出信息可以看出,5号线程调用同步化方法hit()时,该方法中循环还未运行结束,6号线程就又调用hit()输出信息,这违背了同步化方法机制;
B. 从输出信息可以看出,6号线程调用同步化方法hit()结束后,5号线程才能调用hit()输出信息,这符合了同步化方法机制;
C. 同A