Передав это в конструкторе - PullRequest
0 голосов
/ 29 декабря 2018

Я наткнулся на некоторый код вызова JMS, который инициализирует сеанс JMS внутри своего конструктора.Вызывающий код реализует интерфейс ExceptionListener и передает ссылку на this объекту фабрики соединений, как показано ниже:

public class JmsCode implements ExceptionListener {

    private static final Logger logger = LoggerFactory.getLogger(JmsCode.class);

    public JmsCode(String url, String username, String password, String trustStorePath, char[] trustStorePassword) throws JMSException {
        ActiveMQSslConnectionFactory connectionFactory = new ActiveMQSslConnectionFactory(url);
        connectionFactory.setUserName(username);
        connectionFactory.setPassword(password);
        connectionFactory.setTrustStore(trustStorePath);
        connectionFactory.setTrustStorePassword(new String(trustStorePassword));
        connectionFactory.setExceptionListener(this);

        Connection connection = connectionFactory.createConnection();
        connection.start();
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
    }

    @Override
    public void onException(JMSException e) {
        logger.error("Unexpected JMS exception caught", e);
    }

}

Мне интересно, безопасно ли передавать ссылку на это из конструктора JmsCode, учитывая, что объект еще не полностью построен.Я столкнулся с похожим вопросом , в котором я читал статью о том, что IBM не публикует this во время строительства .Хотя я согласен с их аргументацией, я не уверен, применима ли она в этом случае, поскольку единственное, что делает прослушиватель исключений, это регистрация через статический и последний член.Является ли приведенный выше код безопасным (игнорируя, что кто-то еще испытывает желание изменить метод прослушивания исключений для использования некоторого состояния экземпляра объекта)?

Ответы [ 3 ]

0 голосов
/ 29 декабря 2018

Это на самом деле небезопасная публикация, и теоретически возможно, что другой объект увидит этот объект в несогласованном состоянии.

Это говорит о том, что это нехорошая схема (и она просто показана здесь дляпродемонстрируйте ExceptionListener), логика конструктора показывает, что класс фактически полностью создан к тому времени, когда ссылка this уходит (потому что ему нечего строить), и поэтому в этом конкретном случае нет ничего, что можнонеправильно.

0 голосов
/ 29 декабря 2018

Безопасно это или нет, зависит от того, где эта ссылка на this может ускользнуть от до .Если вследствие этого вызова this может быть прочитан другим потоком, то это небезопасно.

Если вы хотите убедиться, что экземпляр полностью инициализирован для безопасной публикации и вы хотите опубликовать его, конструктор не является подходящим местом для его публикации.Вместо этого вам нужно создать объект Factory или статический метод factory, который может безопасно создать объект, а затем опубликовать его перед возвратом вызывающей стороне.

0 голосов
/ 29 декабря 2018

Это полностью безопасно.Вы просто передаете ссылку this, не используя ничего в области действия this.

Что-то пойдет не так, если метод .setExceptionListener(this) выполняет что-то еще, кроме того, что он установщик.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...