zqs164
2018-05-05 16:50
采纳率: 60%
浏览 814
已采纳

java synchronized 同步问题

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

 public class A{
     public synchronized void haha(){

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

            }
        }
     }
 }
  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

12条回答 默认 最新

  • 默默悟问 2018-05-06 04:17
    已采纳
     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);  
      }
    
    }
    
    
    点赞 打赏 评论
  • blownewbee 2018-05-05 17:19

    不能,你的代码只能保证两个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();
                }
            }
         }
     }
    
    点赞 打赏 评论
  • wffancy 2018-05-06 01:50

    除了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();
    }

    }
    

    }

    点赞 打赏 评论
  • 周祭酒 2018-05-06 02:40

    这个是同步锁范围的问题

      public class A{
         public synchronized void haha(){ // 这样写时锁住同一对象的方法,new两个A在不同线程里运行haha是不同步的
    
         }
         class B extends TimerTask{
            @Override
            public void run(){
                synchronized(A.this){ // 这样写是全局锁,锁住的是A这个类,但是这里写得又有点奇怪,为什么B类要用A类加锁
    
                }
            }
         }
     }
    
    点赞 打赏 评论
  • 请叫我站长 2018-05-06 02:57

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

    点赞 打赏 评论
  • 默默悟问 2018-05-06 04:14

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

    点赞 打赏 评论
  • 默默悟问 2018-05-06 04:14

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

    点赞 打赏 评论
  • 默默悟问 2018-05-06 04:18

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

    图片说明

    点赞 打赏 评论
  • jlzg 2018-05-06 07:36

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

    点赞 打赏 评论
  • baidu_15438619 2018-05-06 08:53

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

    点赞 打赏 评论
  • NullPoint99999 2018-05-07 08:01

    可以的,两个锁对象是同一个,这是非静态内部类对象的创建方式,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);
            }
        }
     }
    
    点赞 打赏 评论
  • speedyao 2018-05-08 09:34

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

    点赞 打赏 评论

相关推荐 更多相似问题