Наиболее очевидный пример - использование локального хранилища потоков.См. Пример ниже:
class SomeClass {
// This map needs to be thread-safe
private static final Map<Thread,UnsafeStuff> map = new ConcurrentHashMap<>();
void calledByMultipleThreads(){
UnsafeStuff mystuff = map.get(Thread.currentThread());
if (mystuff == null){
map.put(Thread.currentThread(),new UnsafeStuff());
return;
}else{
mystuff.modifySomeStuff();
}
}
}
* * * * * * * * * * * * * * * * * * * * * * * * Объекты UnsafeStuff
сами могут "использоваться совместно" с другими потоками в том смысле, что если вы передадите другой поток вместо Thread.currentThread()
во время выполнения, на картуget
метод, вы получите объекты, принадлежащие другим потокам.Но вы решили не .Это «использование, которое ограничено потоком».Другими словами, условия runtime таковы, что объекты в действительности никогда не разделяются между различными потоками.
С другой стороны, в приведенном ниже примере объект автоматически ограничивается потоком, и, так сказать, «сам объект» ограничивается потоком.Это в том смысле, что невозможно получить ссылку из других потоков независимо от условий выполнения:
class SomeClass {
void calledByMultipleThreads(){
UnsafeStuff mystuff = new UnsafeStuff();
mystuff.modifySomeStuff();
System.out.println(mystuff.toString());
}
}
Здесь UnsafeStuff
выделяется внутри метода и выходит из области видимости, когдаметод возвращает .. Другими словами, спецификация Java статически гарантирует, что объект всегда ограничен одним потоком.Таким образом, не условие выполнения или способ его использования обеспечивает ограничение, а скорее спецификацию Java.
Фактически, современная JVM иногда выделяет такие объекты в стеке, в отличие от первого примера (лично я не проверял это, но я не думаю, что, по крайней мере, современные JVM это делают).
Покадругими словами, в первом примере JVM не может быть уверена в том, что объект ограничен потоком, просто заглянув внутрь calledByMultipleThreads()
(кто знает, что другие методы связывают с SomeClass.map
).В последнем примере это может.
Редактировать: Но что, если я все еще хочу поделиться объектом с другим потоком?Предположим, что после того, как поток A завершает работу с объектом O, поток B хочет получить доступ к O. В этом случае, может ли O по-прежнему ограничиваться B после того, как с ним покончено?
Я не думаю, чтов этом случае оно называется «ограниченным».Когда вы делаете это, вы просто гарантируете, что к объекту нет доступа одновременно.Так работает параллелизм EJB.Вам все еще нужно «безопасно опубликовать» обсуждаемый общий объект в потоках.