本帖最后由 Kanepan 于 2010-01-07 12:54:47 编辑

解决方案 »

  1.   

    B执行完了dothis,不就解锁了么?
    然后C就执行2步add啊
    我不明白楼主纠结所在?
    run里面只是线程要执行的序列,不代表该进程要一直跑,跑完了重新跑,再跑是不是这么一说来着,楼下继续
      

  2.   


    public synchronized void dothis(messages){ 
        try { 
            Thread.sleep(4000); 
            System.out.println(messages); 
            messages.clear(); 
        } catch (InterruptedException e) { 
            e.printStackTrace(); 
        } 
    }改一下,看这样行不?
      

  3.   


    C 执行add的时候,message对象已经被锁住了,按理说应该被锁住的,为什么还能继续操作?
      

  4.   


    其他方法貌似可行的,只是工作需求只想把messages对象锁住。 ,但是就是搞不懂为什么锁不住对象。
      

  5.   

    额。。我想说我自己的怎么跑出来这么多人
    我去跑过代码了,也分析了原因。有些改动。先代码import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;public class SynchronizedTest {
        public static void main(String[] args) {
            ExecutorService es = Executors.newCachedThreadPool();
            A a = new A();
            B b = new B(a);
            C c = new C(a);
            es.submit(b);
            es.submit(c);
        }
        
    }class A{
        private List<Integer> messages = new ArrayList<Integer>();
        
        public void add(int message){
         synchronized(messages){
         messages.add(message);
         }
        }
        
        public List<Integer> getMessages() {
            return messages;
        }    public void setMessages(List<Integer> messages) {
            this.messages = messages;
        }    public void dothis(){
            synchronized(messages){
                try {
                    System.out.println(messages);
                    Thread.sleep(1000);
                    System.out.println("now" + messages);
                    messages.clear();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }class B implements Runnable{
        private A a;
        public B(A a){
            this.a  = a;
        }
        @Override
        public void run() {
            System.out.println("start thread b");
            a.dothis();
        }
    }class C implements Runnable{
        private A a;
        public C(A a){
            this.a  = a;
        }
        @Override
        public void run() {
            System.out.println("start Thread c");
            a.add(1);
            a.add(2);
            System.out.println("next Thread "+ a.getMessages());
        }
    原因很简单,2楼所说的synchronized的使用方法好像也是不行的,同样需要在add方法上添加synchronized
    但是呢,Thinking in Java比较推荐的是楼主原先的方法,于是我就按照楼主的方法来改了。
    楼主的这种锁的机制在于,只有在使用synchronized的地方才对被synchronized持有的变量进行检测,看是否被其他线程掌握了。
    你只有dothis中检测,但是你的C不执行dothis,而是add所以我在add中添加了synchronized语句楼主可以试下我的代码