你看到一个方法例如public int get()事实上在jvm在执行的时候在执行多个指令来完成的 由于有多个thread在执行  那么这样的操作一定要同步因为多个线程在访问一个共享的数据

解决方案 »

  1.   

    这肯定的,A这个数是可能很多线程在同时进行+的操作,不同步的话,我想各个线程GET到的A都不一样,那+后的结果可想而知.......
      

  2.   

    我怎么觉得increase方法需要同步,而get方法是不需要同步的
      

  3.   

    increase()倒是的确应该同步,effective java上提到过
      

  4.   

    increase应该同步,get不用同步吧!想一下数据库的同步。
      

  5.   

    除非是:
    public synchronied int  get()
      {
        increase();
        return a;
      }
    那么就应该同步了!
      

  6.   

    re!!increase()需要同步  不然increase()很可能会丢是一些操作 楼主哪里来的程序啊
      

  7.   

    感觉这个类设计的有问题
    想像一下这种情况:
    某个客户在使用这个类,要用到里面的变量a
    首先使用get方法,假如说得到的是3
    然后做其他处理
    在该客户处理过程中,其他客户对a进行了修改,即调用increase方法
    此时a为4
    但第一个客户仍然认为a是3
    然后第一个客户调用increase,期望a是4,以便对这种情况做相应操作(假设该客户没有想到会有其他人修改a,因为各个方法只是调用本身是同步的,调用完毕后就不再影响)
    结果a的值是5,因此第一个客户得到的结果必然有误想要解决这种情况的问题
    只有对操作加锁
    就是第一个客户在操作这个类的某个实例(假如这个实例同时被其他客户共享操作)
    必须在第一个客户完全操作完成后,其他客户才能调用该实例的方法
    也就是第一个客户,在读取a为3,做自己的操作,然后增加a为4,做相应操作,然后返回之前,其他类都不允许访该改类(不仅仅是不允许修改,也不允许读取。读取的话就会发生上面的情况,读的时候是一个数,用的时候成另外一个数了)
    这样才能保证所有客户得到的实例是同一个状态注:这跟单例模式不是一个意思,不要弄混了
      

  8.   

    谢谢大家,我这是看ibm网站上的一个例子,我觉得get方法使用同步不合理,所以想和朋友们探讨,java.util.Vector的int size()是同步的,大家可以看看Vector的源程序,我下面有两个想法,不知道对不对:
    1 一般的get方法如果需要多次重复从主存中读取,必须要同步,这样会出现数据不一致现象,在本例中不存在这种情况;
    2 如果明确规定,读取的数据必须是最新的,需要同步.如果使用get的线程挂起,而set线程该变了数据,那么get得到的还是老数据,对于可以容忍旧数据的程序来是可以的对于本例(本人认为不合理),本人认为get可以不要同步,望大侠们发言....
      

  9.   

    同步不同步,主要看需求,但就你问题所描述,根本不用同步,
    而且问题中的同步也是无效的,对一个方法加上syncronize根本不起作用.
      

  10.   

    class ClassA
    {
    private int a; public int get()
    {
    increase();
    System.out.print("{ a= " + a);
    try
    {
    Thread.sleep(1000);
    }
    catch(InterruptedException e)
    {
    e.printStackTrace();
    }

    System.out.print(" } ");
    return a;
    }

    public synchronized int getBySync()
    {
    return get();
    }

    public void increase()
    {
    a++;
    }
    }class Caller implements Runnable
    {
       String msg;
       ClassA a;
       Thread thread;
       public Caller(ClassA a)
       {
           this.a = a;
           thread = new Thread(this);
           thread.start();
       }
       public void run()
       {
           a.get();
       }   
    }class CallerBySync implements Runnable
    {
       String msg;
       ClassA a;
       Thread thread;
       public CallerBySync(ClassA a)
       {
           this.a = a;
           thread = new Thread(this);
           thread.start();
       }
       public void run()
       {
           a.getBySync();
       }   
    }class Test 
    {
    private void test()
    {
    ClassA a = new ClassA();
    Caller c1 = new Caller(a);
    Caller c2 = new Caller(a);
    Caller c3 = new Caller(a);
    try
    {
    c1.thread.join();
    c2.thread.join();
    c3.thread.join();
    }
    catch(InterruptedException e)
    {
    e.printStackTrace();
    }

    }
    private void testBySync()
    {
    ClassA a = new ClassA();
    CallerBySync c1 = new CallerBySync(a);
    CallerBySync c2 = new CallerBySync(a);
    CallerBySync c3 = new CallerBySync(a);
    try
    {
    c1.thread.join();
    c2.thread.join();
    c3.thread.join();
    }
    catch(InterruptedException e)
    {
    e.printStackTrace();
    }
    }

    public static void main(String[] args)
    {
    Test t = new Test();
    t.test();
    System.out.println("以下是使用同步的不同");
    t.testBySync();
    }
    }
      

  11.   

    输出结果如下:
    { a= 1{ a= 2{ a= 3 }  }  } 以下是使用同步的不同
    { a= 1 } { a= 2 } { a= 3 } Press any key to continue...t.test() 没有阻止三个线程同时调用同一对象的同一方法的方法存在。
    t.testBySync()通过线程同步防止了在一个线程使用getBySync()即get()时其它线程进入该方法。
    通过synchronized防止状态出现竞争。
      

  12.   

    不解--thread.join()有什么用处??