Являются ли конструкторы и / или инициализации потокобезопасными? - PullRequest
0 голосов
/ 18 апреля 2020

Представьте себе следующий класс.

class Whatever {
    Object obj;
    Whatever() {
        obj = new Object();
    }
    Object get() {
        return obj;
    }
}

Поскольку потоки обычно записывают в свой локальный кэш, я предполагаю следующее:

Если поток A создает экземпляр Whatever и поток B вызывает get() для этого экземпляра, может случиться так, что B получит null, поскольку ссылка на obj была записана в кеше локали только A, не в общем кэше.

Я прав? А как насчет других видов инициализации?


Я пытался создать такое поведение с помощью следующего кода.

class Main {

    static Whatever whatever = new Whatever();


    static class Whatever {
        Object obj;
        Whatever() {
            obj = new Object();
        }
    }


    public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            while (!Thread.interrupted()) {
                whatever = new Whatever();
            }
        });
        Thread t2 = new Thread(() -> {
            while (!Thread.interrupted()) {
                System.out.println(whatever.obj);
            }
        });

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

        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        t1.interrupt();
        t2.interrupt();
    }
}

Вывод никогда не бывает null, но я думаю, что это должно быть иногда. Может быть, код просто пытается ошибочно ..

...