Java中同步方法的正确方法

Java中同步方法的正确方法,java,multithreading,synchronized,Java,Multithreading,Synchronized,我有一个示例类: public class LocksAndSynchronization { private Object lock1 = new Object(); private Object lock2 = new Object(); static int count; public void methodOne() { for (int i = 1; i <= 10000; i++) { count+

我有一个示例类:

public class LocksAndSynchronization {

    private Object lock1 = new Object();
    private Object lock2 = new Object();

    static int count;

    public void methodOne() {

        for (int i = 1; i <= 10000; i++) {
            count++;
        }

    }

    public void methodTwo() {

        for (int i = 1; i <= 10000; i++) {
            count++;
        }

    }

    public synchronized void process() {
        methodOne();
        methodTwo();
    }

    public static void main(String[] args) throws InterruptedException {
        final LocksAndSynchronization l = new LocksAndSynchronization();
        Thread t1 = new Thread() {

            @Override
            public void run() {
                l.process();
            }

        };

        Thread t2 = new Thread() {

            @Override
            public void run() {
                l.process();
            }

        };


        t1.start();
        t2.start();

        t1.join();
        t2.join();


        System.out.println("count: " + count);

    }

}
公共类锁和同步{
私有对象lock1=新对象();
私有对象锁2=新对象();
静态整数计数;
公共方法一(){

对于(int i=1;i建议同步尽可能少的代码,因为它会生成冲突(其他线程正在等待)。因此,方法1更可取。

建议同步尽可能少的代码,因为它会生成冲突(其他线程正在等待)。因此,方法1更可取。

计数是静态的,所以它对所有对象都是相同的。所以您需要以静态方式同步进程。为此,请创建一个静态锁并使用它

static Object staticObject = new Object();
public void process() {
   synchronized( staticObject){
      methodOne();
      methodTwo();
   }
}
或者您可以将methodOne和methodTwo进行同步

static Object staticObject = new Object();
public void methodOne() {
    synchronized( staticObject){
      for (int i = 1; i <= 10000; i++) {
          count++;
      }
    }
}

public void methodTwo() {
    synchronized( staticObject){
      for (int i = 1; i <= 10000; i++) {
          count++;
      }
    }
}
static Object staticObject=new Object();
公共方法一(){
已同步(静态对象){

for(int i=1;icount是静态的,所以它对所有对象都是相同的。所以您需要以静态方式同步进程。为此,创建一个静态锁并使用它

static Object staticObject = new Object();
public void process() {
   synchronized( staticObject){
      methodOne();
      methodTwo();
   }
}
或者您可以将methodOne和methodTwo进行同步

static Object staticObject = new Object();
public void methodOne() {
    synchronized( staticObject){
      for (int i = 1; i <= 10000; i++) {
          count++;
      }
    }
}

public void methodTwo() {
    synchronized( staticObject){
      for (int i = 1; i <= 10000; i++) {
          count++;
      }
    }
}
static Object staticObject=new Object();
公共方法一(){
已同步(静态对象){

对于(int i=1;i我更喜欢同步
methodOne
methodTwo
,因为它们可以从对象外部调用。也可以在不嵌入
进程的情况下调用它们。因此,每个方法都应该以线程安全的方式单独实现


希望有帮助。

我更喜欢同步
methodOne
methodTwo
,因为它们可以从对象外部调用。它们也可以在不嵌入
进程的情况下调用。因此,每个方法都应该以线程安全的方式单独实现


希望对您有所帮助。

无论您是同步
进程
还是单独同步任何方法,method1和method2之间都不会有一致性(即变量
计数
不会在这些调用之间更改)。原因是变量
count
是静态的,因此即使它是从
同步的
方法中使用的,它也不是线程安全的。

无论您是同步
进程
还是单独同步任何方法,方法1和方法2之间都不会有一致性(即变量
count
在这些调用之间不会更改)原因是变量
count
是静态的,因此即使它是从
synchronized
方法中使用的,也不是线程安全的。

正如Adem所说,静态“count”字段需要一个静态锁。但是这里有一个更大的接口设计问题。
methodOne
methodTwo
都是公共的这意味着它们可以从任何其他类调用。如果它们需要在同步上下文中执行,则建议它们都使用同步机制


如果
methodOne
methodTwo
不是公开的,我更倾向于在更高级别上执行同步(因为这样更高效、更灵活),即在
过程中
方法中,然后对其他两个方法进行注释,这两个方法指定必须从同步上下文调用它们。

正如Adem所说,静态“count”字段需要静态锁。但是这里有一个更大的接口设计问题。
方法一
方法二
都是公开的lic意味着它们可以从任何其他类调用。如果要求它们在同步上下文中执行,则建议它们都使用同步机制


如果
methodOne
methodTwo
不是公开的,我更倾向于在更高级别上执行同步(因为这样更高效、更灵活),即在
过程中
方法中,然后对其他两个方法进行注释,这两个方法指定必须从同步上下文中调用它们。

简化的代码不便于识别问题的实质。首先,
计数
是静态的,因此在实例级锁定无法工作,但这可能会导致错误别让人分心

一个更重要的考虑因素是
methodOne
methodTwo
,这两个公共方法显然需要同步,但它们自己都不需要。如果您选择只同步
进程
方法,这意味着您需要
methodOne
methodTwo的所有其他调用方e> 还要适当地注意同步,这看起来很不稳定


此外,如果您不需要将整个
过程
分解为原子步骤,并且它可以分解为两个独立的原子步骤,那么按照这些语义进行锁定更为自然。这取决于您是否从程序中的其他地方调用
methodOne
methodTwo

您的简化代码代码并不能让你很容易辨别问题的本质。首先,
count
是静态的,所以在实例级别锁定无法工作,但这可能只是一个干扰

一个更重要的考虑因素是
methodOne
methodTwo
,这两个公共方法显然需要同步,但它们自己都不需要。如果您选择只同步
进程
方法,这意味着您需要
methodOne
methodTwo的所有其他调用方e> 还要适当地注意同步,这看起来很不稳定

此外,如果您不需要整个
过程
是原子的,并且它可以分解为两个独立的原子步骤,t