Как заблокировать отдельные методы в общем классе утилит? - PullRequest
1 голос
/ 28 января 2011

Я написал следующий код:

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));
        }
    }
}

Как мне обеспечить, чтобы объекты AddThread и MultiplyThread могли получать блокировки для методов add(int op1, int op2) и multiply(int op1, int op2) соответственно одновременновремя не блокируя друг друга?

Другими словами, я хочу убедиться, что два метода класса UtilityCalculator могут использоваться одновременно двумя потоками в любой момент времени.Как мне этого добиться?Я что-то упустил в коде?

Ответы [ 2 ]

3 голосов
/ 28 января 2011

Вы уже сделали это - вы синхронизируете на разных объектах, так что все должно быть хорошо.Есть ли какая-то причина, по которой вы подозреваете, что это не работает?

Чтобы сделать более очевидным, что работает , поместите на секунду в спящий режим каждый из блоков синхронизации.Ваша программа все равно выполнит все 20 операций за 10 секунд, показывая, что потоки не блокируют друг друга.

2 голосов
/ 28 января 2011

Эти два метода уже используют два разных объекта для синхронизации, поэтому вы уже можете вызывать и одновременно выполнять add и multiply из разных потоков.

Кроме того, я предполагаю, что вы это знаете, но я должен добавить это, просто чтобы быть уверенным: этот метод не требует какой-либо синхронизации как все, поскольку они по своей природе поточно-ориентированы.Если реальный код предназначен только для демонстрации, не стесняйтесь игнорировать это.

...