Java 如何在公共实用程序类中锁定单个方法?

Java 如何在公共实用程序类中锁定单个方法?,java,multithreading,synchronization,locking,Java,Multithreading,Synchronization,Locking,我编写了以下代码: public class ClassLevelSynchronization { public static void main(String[] args) { new Thread(new AddThread()).start(); new Thread(new MultiplyThread()).start(); } } class UtilityCalculator{ private static final

我编写了以下代码:

public class ClassLevelSynchronization {
    public static void main(String[] args) {
        new Thread(new AddThread()).start();
        new Thread(new MultiplyThread()).start();
    }
}

class UtilityCalculator{
    private static final Object ADD_LOCK = new Object();
    private static final Object MULTIPLY_LOCK = new Object();

    public static int add(int op1, int op2){
        synchronized (ADD_LOCK) {
            return op1+op2;
        }       
    }

    public static int multiply(int op1, int op2){
        synchronized (MULTIPLY_LOCK) {
            return op1*op2;
        }       
    }
}

class AddThread implements Runnable{
    public void run() {     
            for (int i = 0; i < 10; i++) {
                System.out.println("Addition of: "+i+" + "+(i+1)+" = "+UtilityCalculator.add(i, i+1));
            }   
    }
}

class MultiplyThread implements Runnable{
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println("Multiplication of: "+i+" * "+(i+1)+" = "+UtilityCalculator.multiply(i, i+1));
        }
    }
}
公共类类级别同步{
公共静态void main(字符串[]args){
新线程(newaddthread()).start();
新线程(新的MultiplyThread()).start();
}
}
类实用计算器{
私有静态最终对象ADD_LOCK=new Object();
私有静态最终对象乘法_锁=新对象();
公共静态int-add(int-op1,int-op2){
已同步(添加锁定){
返回op1+op2;
}       
}
公共静态整数乘法(整数op1,整数op2){
同步(倍增锁定){
返回op1*op2;
}       
}
}
类AddThread实现可运行{
public void run(){
对于(int i=0;i<10;i++){
System.out.println(“添加:”+i+“+”+”+(i+1)+“=”+实用计算器.add(i,i+1));
}   
}
}
类MultiplyThread实现可运行{
公开募捐{
对于(int i=0;i<10;i++){
System.out.println(“乘法:”+i+“*”+(i+1)+“=”+实用计算器.multiply(i,i+1));
}
}
}
如何确保
AddThread
MultiplyThread
的对象可以分别同时获取
add(int op1,int op2)
multiply(int op1,int op2)
方法的锁,而不相互阻塞


换句话说,我想确保
UtilityCalculator
类的两个方法可以在任何给定时间由两个线程同时使用。我如何做到这一点?我在代码中遗漏了什么吗?

您已经完成了-您正在不同的对象上进行同步,所以应该可以。你怀疑这不起作用有什么原因吗


为了更清楚地表明它正在工作,请在每个同步块内休眠一秒钟。您的程序仍将在大约10秒钟内执行所有20个操作,这表明线程没有相互阻塞。

您已经完成了这项操作-您正在不同对象上同步,因此应该可以。你怀疑这不起作用有什么原因吗

为了更清楚地表明它正在工作,请在每个同步块内休眠一秒钟。您的程序仍将在大约10秒内执行所有20个操作,这表明线程没有相互阻塞。

这两种方法已经使用两个不同的对象进行同步,因此您已经可以从不同的线程同时调用和执行
add
multiply

另外,我假设您知道这一点,但我必须添加它,以确保:这些方法不需要任何同步,因为它们本质上是线程安全的。如果实际代码只是为了演示,那么可以忽略这一点。

这两种方法已经使用了两个不同的对象进行同步,因此您已经可以从不同的线程同时调用和执行
add
multiply


另外,我假设您知道这一点,但我必须添加它,以确保:这些方法不需要任何同步,因为它们本质上是线程安全的。如果实际的代码只是为了演示,那么可以忽略这一点。

实际上,当我编写以下语句时,我不理解这一点:UtilityCalculator.add(I,I+1);它如何获取用于加法的锁,更重要的是,它为什么不同时获取用于乘法的锁,从而阻止另一个线程?@n\u g:该语句本身不获取锁-
add
方法中的同步块会获取锁。多个线程可以同时进入
add
方法,但在任何时候只有一个线程会进入同步块。实际上,当我编写以下语句时,我不理解这一点:UtilityCalculator.add(I,I+1);它如何获取用于加法的锁,更重要的是,它为什么不同时获取用于乘法的锁,从而阻止另一个线程?@n\u g:该语句本身不获取锁-
add
方法中的同步块会获取锁。多个线程可以同时进入
add
方法,但在任何时候只有一个线程会进入同步块。谢谢Joachim!!!是的,代码仅用于演示。但是你说这些方法本质上是线程安全的。这是怎么回事?他说“这些方法是线程安全的”,意思是这些方法不会改变父对象的状态,因此没有副作用。这些方法也被称为重入方法:重入方法是可以安全地进入的方法,即使相同的方法正在进行中,也可以进一步进入调用堆栈(相同线程的)。以这种方式使用不可重入的方法是不安全的。谢谢Joachim!!!是的,代码仅用于演示。但是你说这些方法本质上是线程安全的。这是怎么回事?他说“这些方法是线程安全的”,意思是这些方法不会改变父对象的状态,因此没有副作用。这些方法也被称为重入方法:重入方法是可以安全地进入的方法,即使相同的方法正在进行中,也可以进一步进入调用堆栈(相同线程的)。以这种方式使用不可重入的方法是不安全的。