为什么用单独的锁而不是对在Java的同步块中被修改的对象进行锁是一个好习惯? [英] Why is it a good practice to have separate locks instead of having lock on object that get modified in the synchronized block in java?

查看:108
本文介绍了为什么用单独的锁而不是对在Java的同步块中被修改的对象进行锁是一个好习惯?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

虽然我要讲的很少是Java Thread教程,但是我要遵循以下语句.

While I am going though few Java Thread tutorials I got to the following statement.

有一个好习惯,那就是使用单独的锁定对象,而不是在同步块中修改对象的时钟. Java基础代码优化可能会产生影响.

It's a good practice to have separate lock objects instead of having clock on object that get modified in the synchronized block. Java underlying code optimization may create implications.

它确切说明了什么?

说我有以下代码来暗示这种情况.

Say I have code as follows to imply the situation.

 public class TestSynch(){
   private Object lock1;
   private Object lock2;

   private List<Integer> list1;
   private List<Integer> list2;

   public void doListOne(){
     synchronized(lock1){
        // some server processing
        list1.add(/*some random number using random generator*/);
     }
   }
   public void doListTwo(){
     synchronized(lock1){
        // some server processing
        list2.add(/*some random number using random generator*/);
     }
   }
 }

说我有一些方法在一个循环中依次调用上述两个方法,而该方法被两个不同的线程调用.

Say I have some method calling the above two methods sequentially in a loop and that method is being called by two different threads.

如果我使用list1和list2而不是lock1和lock2,那么对Java代码优化有何意义?

What would be implication with respect to Java code optimization if I use list1 and list2 instead of lock1 and lock2?

推荐答案

如果我使用list1和list2而不是lock1和lock2,那么对Java代码优化有何意义?

What would be implication with respect to Java code optimization if I use list1 and list2 instead of lock1 and lock2?

这与优化无关,而与封装有关.

It's not about optimization, it's about encapsulation.

在您的示例中,在列表对象上进行同步与在单独的锁对象上进行同步之间没有实际区别.

In your example, there would be no practical difference between synchronizing on the list objects vs. synchronizing on separate lock objects.

私有锁对象的正常用例是当类用作 monitor 时.监视器的经典实现如下所示:

The normal use-case for a private lock-object is when the class functions as a monitor. The classic implementation of a monitor looks like this:

class MyMonitor {
    synchronized foo(...) { ... }
    synchronized bar(...) { ... } 
    synchronized baz(...) { ... }
}

做同一件事的私人锁方式看起来像

The private-lock way of doing the same thing looks like

class MyMonitor {
    private Object lock = new Object();

    foo(...) { synchronized(lock) { ... } }
    bar(...) { synchronized(lock) { ... } } 
    baz(...) { synchronized(lock) { ... } }
}

采用经典方法的问题"是MyMonitor类的客户端可能会使用MyMonitor实例来同步其他内容:

The "problem" with doing it the classic way is that the client of the MyMonitor class potentially could use a MyMonitor instance to synchronize something else:

MyMonitor myMonitor = ...;

synchronized( myMonitor ) { ... }

为什么有人会写那个?我不知道.但是,如果有人这样做,则客户端将myMonitor对象用作锁可能会干扰MyMonitor类将同一对象用作锁.

Why would anybody ever write that? I have no idea. But if somebody did, then the client's use of a myMonitor object as a lock could interfere with the MyMonitor class's use of the same object as a lock.

第二种方法,使用私有锁对象,可以确保即使客户端确实使用MyMonitor锁定其他内容,也不会干扰MyMonitor实例的私有锁.

The second way, using the private lock object, insures that even if the client does use a MyMonitor for locking something else, it can't possibly interfere with the MyMonitor instance's private lock.

这都不适用于您的示例,因为在您的示例中,列表是(可能)对客户端不可见的私有变量.

None of this really applies to your example, because in your example the lists are private variables that (presumably) are not visible to clients.

这篇关于为什么用单独的锁而不是对在Java的同步块中被修改的对象进行锁是一个好习惯?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆