Ответ 1
Я думаю, вам нужно различать то, что вы уже сохранили в памяти и исполнение кода.
В Singleton Object у вас есть:
- Поля: они хранятся в памяти. Они могут быть разделены между несколькими потоками, и у вас нет гарантии, что они будут поддерживать последовательность (если вы не синхронизируете их).
- Методы, которые будут называться: их можно вызывать из нескольких потоков. Каждое выполнение является независимым и потокобезопасным, если только они не имеют доступ к некоторому общему полю неправильно.
Теперь перейдем к вашему вопросу: если вы разделите свой одноэлементный объект между несколькими потоками и одновременно получите доступ к нему, каждый отдельный поток выполнит часть объекта Singleton кода, завернутую в его собственное исполнение.
Также, если вы пишете Thread.currentThread().getId();
, который в основном возвращает идентификатор потока, который вы выполняете в методах singleton, вы получите разные идентификаторы, потому что разные потоки выполняют свой собственный стек методов. Являясь апатридом, у вас нет полей в синглтоне, которые будут использоваться среди них!
Слово о безгражданстве и состояниях
Без гражданства означает, что bean не имеет модифицируемого поля для обмена. Это означает, что у вас есть только методы и/или статические вещи в вашем объекте, поэтому вы можете использовать их в любом месте и всегда будете возвращать вам тот же результат. Вам не нужно беспокоиться о синхронизации доступа к полю.
В качестве базового примера о безстоящем, предположим, что у вас есть класс, который выполняет только операцию sum:
public class StatelessClass{
public int sum(int a, int b){
return a+b;
}
}
Точно так же вы можете объявить его как класс abstract (без его создания) и сделать его методы статическими, что означает, что вам не нужен какой-либо экземпляр для вызова его методов:
public abstract class StatelessClass{
/**
* I only sum objects
*/
public static int sum(int a, int b){
return a+b;
}
}
Тогда вы можете использовать его как StatelessClass.sum(1,1);
, это будет очень похоже на объект Singleton, с той разницей, что в Singleton у вас есть уникальный экземпляр, общий для приложения.
Таким же образом, если поле, которое вводится и обеспечивает доступ к службе, не считается измененным состоянием объекта:
public class StatelessServiceClass{
private Service service;
public int sum(int a, int b){
return service.sum(a,b);
}
public void setService(Service serv){
this.service=serv;
}
}
Однако наличие изменяемого поля делает объект stateful:
public class StatefulClass{
//This fields make the object STATEFUL
private int totalSum = 0;
public int sum(int a, int b){
int sum = a + b;
totalSum = totalSum + sum;
if (totalSum > 100)
System.out.println("This thread "+Thread.currentThread().getId()+
+" got it!");
return sum;
}
}
В качестве sum
можно обращаться несколькими потоками одновременно, вы должны гарантировать, что totalSum
будет выполняться синхронизированным образом. Отпечатанное предложение не гарантируется, если вы не сделаете это.
Все это также правильно объяснено в этом ответе Threadsafety
часть @BalusC.