java synchronized 同步问题

请问通过下面这种方法能起到防止haha()和run()中的synchronized中的内容同时执行的作用吗?

 public class A{
     public synchronized void haha(){

     }
     class B extends TimerTask{
        @Override
        public void run(){
            synchronized(A.this){

            }
        }
     }
 }
 public class A{
  int value = 0;

  final int NUMBER = 1000000;

    public synchronized void haha(){
        for (int i = 0; i < NUMBER; i++)
            value ++;
  }

  class B extends TimerTask{
     @Override
     public void run(){
         synchronized(A.this){
            for (int i = 0; i < NUMBER; i++)
                value ++;
         }
     }
  }

  public static void main(String args[]) throws InterruptedException {
    A a = new A();
    B b = a.new B();

    ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(2);

    executor.scheduleWithFixedDelay(b, 1, 1, TimeUnit.SECONDS);
    executor.scheduleWithFixedDelay(new Runnable() {

            @Override
            public void run() {
                a.haha();
            }

    }, 1, 1, TimeUnit.SECONDS);

    Thread.sleep(1000 * 9 + 500);

    executor.shutdownNow();

    System.out.printf("value: %d\n", a.value);  
  }

}

不能,你的代码只能保证两个haha或者两个run不能同时运行

你需要用lock来实现haha和run的同步

注意,要java8以上才支持lock

 public class A{
private Lock lock = new ReentrantLock();
     public synchronized void haha(){
 lock.lock();
 ...
 lock.unlock();
     }
     class B extends TimerTask{
        @Override
        public void run(){
 lock.lock();
 ...
 lock.unlock();
            }
        }
     }
 }

除了synchronized,可以锁lock实现同步
public class LockTest {

/**
 * @param args
 */
public static void main(String[] args) {
    // TODO Auto-generated method stub
    final Business business = new Business();
    ExecutorService service = Executors.newFixedThreadPool(3);
    for(int i=0;i<3;i++){
        service.execute(new Runnable(){
            public void run(){
                business.service();
            }
        });
    }

    service.shutdown();
}

}

class Business{
private int count = 0;
Lock lock = new ReentrantLock();
public void service(){
lock.lock();
count++;
try {
Thread.sleep(10);
System.out.println(count);

} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
lock.unlock();
}

}

}

这个是同步锁范围的问题

  public class A{
     public synchronized void haha(){ // 这样写时锁住同一对象的方法,new两个A在不同线程里运行haha是不同步的

     }
     class B extends TimerTask{
        @Override
        public void run(){
            synchronized(A.this){ // 这样写是全局锁,锁住的是A这个类,但是这里写得又有点奇怪,为什么B类要用A类加锁

            }
        }
     }
 }

不能的,如果你需要两个方法不能同时执行,最好的方法是使用同一把锁。比如使用A.class作为锁,而不是A.this .A.this不能保证两个实例运行时同时进入两个方法。

不知道为什么我的回复被删除了。我的答案是可以的,还写了测试代码验证也是可以的。这不是很好的方式,但确实是可以。

@系统管理员,实在的回复也能被删!!!

截图为证,已经不止一次删了我的实在回复了。

图片说明

不能。两个锁是在不同的对象上面。

你这个是锁的实例,两个方法不能同时运行要锁同一个对象

可以的,两个锁对象是同一个,这是非静态内部类对象的创建方式,A a = new A(); B b = a.new B();像这种问题自己实验一下就清楚了,
public static void main(String[] args){
g g0 = new g();
g0.haha();
g0.new B().run();
}
public synchronized void haha(){

    System.out.println(this);

}
class B extends TimerTask{
    @Override
    public void run(){
        synchronized(this){
            System.out.println(this);
        }
    }
 }

synchronized 方法锁是当前对象,下面的run也是当前对象。如果你的这两个方法执行都是同一个A对象那么可以达到你的预期,如果haha是一个对象,run是另一个对象的内部类对象,那么达不到同时锁的预期,望采纳