Используйте синхронизированный или не приведенный ниже код, генерирующий одинаковый хеш-код для всех потоков. Как? - PullRequest
0 голосов
/ 01 июля 2018

«мы синхронизируем метод глобального доступа, чтобы только один поток мог одновременно выполнять метод getInstance», не используя ключевое слово синхронизированного кода ниже, уже действующее как потокобезопасное.

Car.java

public class Car {

private static Car car;

private Car() {
    // TODO Auto-generated constructor stub
}

public static Car getInstance(){
    if(car==null){
        car=new Car();
    }
    return car;
}
}

Test.java

public class Test {
public static void main(String[] args) {
    Thread t1=new Thread(new Runnable() {

        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName()+" Running");
            System.out.println(Car.getInstance().hashCode());
            System.out.println(Thread.currentThread().getName()+" Finishing");
        }
    });
    t1.start();

    Thread t2=new Thread(new Runnable() {

        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName()+" Running");
            System.out.println(Car.getInstance().hashCode());
            System.out.println(Thread.currentThread().getName()+" Finishing");
        }
    });

    t2.start();

    Thread t3=new Thread(new Runnable() {

        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName()+" Running");
            System.out.println(Car.getInstance().hashCode());
            System.out.println(Thread.currentThread().getName()+" Finishing");
        }
    });
    t3.start();
    }
}

выход

Thread-0 Running
1828451009
Thread-0 Finishing
Thread-1 Running
1828451009
Thread-1 Finishing
Thread-2 Running
1828451009
Thread-2 Finishing

Без использования синхронизированного метода хэш-код одинаков во всех случаях потока, как?

Ответы [ 2 ]

0 голосов
/ 01 июля 2018

Планирование потоков является частью ОС, если вы выполняете код несколько раз, вы обнаруживаете различия. Если вы хотите, чтобы ваш поток кода был безопасным во всех случаях, тогда вы должны использовать синхронизированный блок с двойной блокировкой.

public class Car {

    private static volatile Car car;

    private Car() {
        // TODO Auto-generated constructor stub
    }

    public static Car getInstance(){
    if(car==null){
        synchronized(Car.class) {
           if(car==null)
            car=new Car();
        }
     }
    return car;
  }
}

Примечание: определение всего синхронизированного метода, имеющего производительность выпуск.

https://javarevisited.blogspot.com/2014/05/double-checked-locking-on-singleton-in-java.html

0 голосов
/ 01 июля 2018

Если я запускаю все темы одновременно

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

выходные данные изменяются иногда, один и тот же хэш-код иногда отличается

Thread-1 Running
Thread-2 Running
Thread-0 Running
183297081
Thread-2 Finishing
183297081
Thread-1 Finishing
183297081
Thread-0 Finishing


Thread-0 Running
Thread-2 Running
Thread-1 Running
678111939
1828451009
1828451009
Thread-2 Finishing
Thread-1 Finishing
Thread-0 Finishing


Thread-0 Running
Thread-2 Running
Thread-1 Running
678111939
183297081
558529301
Thread-1 Finishing
Thread-2 Finishing
Thread-0 Finishing

Невозможно понять это поведение

...