powered by simpleCommunicator - 2.0.56     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Spring Component
6 сообщений из 6, страница 1 из 1
Spring Component
    #39693216
Aliara
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день.
Читаю потихоньку про спринг, но в голове пока некоторая каша. Помогите, пожалуйста, разобраться.

Есть два класса. Первый помечен, как компонент. Насколько я поняла, его экземпляр хранится в контейнере в единственном количестве (по умолчанию). То есть все потоки дергают один и тот же экземпляр.
Ниже приведен второй класс, где несколько потоков дергают метод create компонента. Не может ли быть такого, что потоки в какой-то момент пересекутся и я получу не валидный результат (result, частично заполненный каким-нибудь чужим объектом B)
И, получается, в компоненте не стоит объявлять поля класс, значения в которых потом будут меняться в методах, поскольку каждый поток будет менять их на свое значение?
То есть, если я в SpringTest объявляю private int value = 5; В методе create напишу, что-то вроде value=b.getValue3(), а в методе update1 a.setValue3(value), то результат будет несколько непредсказуем?

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
@Component
public class SpringTest {

    public A create(B b){
        A a = new A();
        update1(a, b);
        update2(a,b );
        return a;
    }

    private void update1(A a, B b) {
        a.setValue1(b.getValue1());
    }

    private void update2(A a, B b) {
        a.setValue2(b.getValue2());
    }
}



Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
public class SpringExecutor{

    @Autowired
    SpringTest springTest;

    public void goTest(List<B> listB){
        ExecutorService service = Executors.newFixedThreadPool(3);
        for(B b: listB) {
            service.submit(new Runnable() {
                public void run() {
                  A result =  springTest.create(b);
                }
            });
        }
    }

}
...
Рейтинг: 0 / 0
Spring Component
    #39693232
Tsyklop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Aliara, Все верно. Singleton - тип бина по умолчанию потоконебезопасен, если с этим бином будет производится действия из разных потоков. Поэтому рекомендуется использовать другие типы, такие как prototype, request, session, global-session (последний 3 для веб разработки)
...
Рейтинг: 0 / 0
Spring Component
    #39693233
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Все примитивные типы Java (кроме long) - атомарны по чтению и записи.
С модификатором volatile атомарны все примитивные типы, включая long.
Атомарность сама по себе не означает у вас не будет "неожиданных" значений.

Чтобы "не морщить" лоб в странных местах, Java SE API уже давно содержит пакеты java.util.concurrent, java.util.concurrent.atomic, java.util.concurrent.lock.

P.S.
Технически, при наличии 64-разрядных инструкций процессора long тоже атомарен.
На x86-архитектуре атомарность long гарантируется, как минимум, для процессоров с SSE-расширениями.
По сегодняшним меркам это означает "для всех x86", но на других архитектурах может быть по всякому.
...
Рейтинг: 0 / 0
Spring Component
    #39693250
Aliara
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Tsyklop,

То есть пусть у меня есть класс B
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
public class B {
    private int value1;
    private int value2;
    private int value3;

    B(int v1, int v2, int v3) {
        value1 = v1;
        value2 = v2;
        value3 = v3;
    }
    public int getValue1() {
        return value1;
    }
    public int getValue2() {
        return value2;
    }
    public int getValue3() {
        return value3;
    }
}



Один поток дергает строку
Код: java
1.
 A result =  springTest.create(b);

с B b1 = new b(1,2,3);
А второй поток дергает эту же строку, но с B b2 = new b(4,5,6);

Могу ли я в результате получить экземпляр класса A со значениями value1 =1, а value2=5. То есть одно значение из b1, а второе из b2?
...
Рейтинг: 0 / 0
Spring Component
    #39693334
cossack5
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AliaraTsyklop,

То есть пусть у меня есть класс B
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
public class B {
    private int value1;
    private int value2;
    private int value3;

    B(int v1, int v2, int v3) {
        value1 = v1;
        value2 = v2;
        value3 = v3;
    }
    public int getValue1() {
        return value1;
    }
    public int getValue2() {
        return value2;
    }
    public int getValue3() {
        return value3;
    }
}



Один поток дергает строку
Код: java
1.
 A result =  springTest.create(b);

с B b1 = new b(1,2,3);
А второй поток дергает эту же строку, но с B b2 = new b(4,5,6);

Могу ли я в результате получить экземпляр класса A со значениями value1 =1, а value2=5. То есть одно значение из b1, а второе из b2?
Как вам выше уже написали, синглтоны не thread safe, но это не относится к локальным переменным - в данном случае A a = new A (в каждом потоке будут "свои" локальные переменные).
...
Рейтинг: 0 / 0
Spring Component
    #39693639
denisftw
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Aliara, основная проблема тут не в Singleton'ах самих по себе, а в появлении shared mutable state. Уберите состояние и делайте компоненты Singleton'ами сколько влезет. Собственно, в типичном Веб-приложении 99% компонентов, которые инжектятся - это всякие сервисы, контроллеры, DAO - им состояние ни к чему.
...
Рейтинг: 0 / 0
6 сообщений из 6, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / Spring Component
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]