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!!!是的,代码仅用于演示。但是你说这些方法本质上是线程安全的。这是怎么回事?他说“这些方法是线程安全的”,意思是这些方法不会改变父对象的状态,因此没有副作用。这些方法也被称为重入方法:重入方法是可以安全地进入的方法,即使相同的方法正在进行中,也可以进一步进入调用堆栈(相同线程的)。以这种方式使用不可重入的方法是不安全的。