hjack 发表于 2005-12-10 16:53

JAVA多线程设计模式--Single Threaded Execution Pattern

解决方案:找出实例状态的不稳定的范围即临界区,对临界区加以防护,使同时执行的线程

保持在只有一条的情况。
修改Bridge类,使它成为线程安全的类.在pass与toString两个方法前面加上关键字

synchronized.
修改过的Bridge类如下:

/**
* Bridge类,用来表示行人要通过的独木桥
*/
package single;

public class Bridge {

        private int counter = 0;
        private String name = "nobody";
        private String address = "nowhere";
       
        /**
       * 为通过桥的行人进行统计,并把参数传入的name与address拷贝到对应字段。
       * @param name
       * @param address
       */
        public synchronized void pass(String name,String address){
                this.counter++;
                this.name = name;
                this.address = address;
                check();
        }
       
        /**
       * 显示桥的状态
       */
        public synchronized String toString(){
                return "NO."+counter+":"+name+","+address;
        }
       
        /**
       * 检查桥的状态是否正常,如果行人的第一个字符与出生地的第一个字符不一样
       * 则表示出错,桥会损坏。
       */
        private void check(){
                if(name.charAt(0)!=address.charAt(0)){
                        System.out.println("******broken******"+toString());
                }
        }
}


再执行,则无论等多久都不会出现borken.
Apple begin
Banana begin
Cat begin

为什么可以这样做?
声明为synchronized的方法能够保证同一时间只有一个线程可以执行它.有点类似操作系统里说到的信号量的同步互斥.
当线程Apple执行方法pass时,会获得对象的锁定,线程Banana就会在pass方法的入口处被阻挡下来,直到线程Apple执行完pass方法并解除锁定.线程Banana才可以开始执行pass方法.

[ Last edited by hjack on 2005-12-10 at 16:56 ]

wool王 发表于 2005-12-10 20:56

我来支持了。

这个例子举得挺好,就是楼主画的图。。。我看了想笑。哈哈。

wool王 发表于 2005-12-10 21:05

是不是toString方法可以不修饰成synchronized呢?

因为toString方法在check方法被invoke,check在pass方法被invoke,而线程类只invoke pass方法,所以pass方法修饰成synchronized不就可以了?因为调用到toString的时候线程肯定得老老实实的排队的。

或者hjack你是出于其他哪方面考虑呢?

hjack 发表于 2005-12-10 22:18

呵呵,wool说得有道理,如果invoke可以传递的话,pass方法已是synchronized ,check方法被invoke,而toSting方法是在check里会调用.
我当时是这样想的,check方法没有设置为synchronized ,那么在check里调用toString就可能会出现线程不安全,但按照check是线程安全地访问的话,它里面的函数也应该是线程安全的吧.

wool王 发表于 2005-12-10 23:32

Originally posted by hjack at 2005/12/10 14:18:
呵呵,wool说得有道理,如果invoke可以传递的话,pass方法已是synchronized ,check方法被invoke,而toSting方法是在check里会调用.
我当时是这样想的,check方法没有设置为synchronized ,那么在check里调用toString就 ...

嗯。感觉你将toString设置成public(覆盖Object的方法),估计是会被外部类调用到的吧,那保证他是线程安全的还是必要的,所以加synchronized还是有意义的,我这么认为。
页: [1]
查看完整版本: JAVA多线程设计模式--Single Threaded Execution Pattern