Я считаю, что есть два пути, которые вы можете go:
Опция 1
Поддерживать объект для потока
Это может работать, если вы обращаетесь к дорогостоящему объекту из ограниченного четко определенного набора потоков (читай, используя пул потоков и не создавая потоки каждый раз, что в любом случае происходит во многих приложениях).
В этом случае вы можно использовать ThreadLocal
. Поскольку в одном потоке все должно быть последовательным, вы можете хранить небезопасные для потока объекты в локальном потоке.
Вы можете думать о ThreadLocal как о карте, в которой для каждого потока поддерживается выделенный экземпляр дорогого объекта.
Опция 2
Совместно использовать один (или N в общем) объект между M потоками, чтобы N
Я не знаю о готовом решении для этого, после того, как все ваши объекты вы хотите сохранить, но в целом довольно легко обернуть вашу собственную реализацию, которая обеспечит своего рода блокировку / синхронизированный доступ к объекты для ваших типов объектов.
Диапазон идей для реализации может варьироваться. В качестве идеи: вы можете обернуть реальный объект сгенерированным прокси во время выполнения / времени сборки, что делает его эффективно поточно-ориентированным:
public interface IMyObject {
void inc();
void dec();
}
// this is an object that you would like to make thread safe
public class MyActualObject implements IMyObject {
private int counter = 0;
void inc() {counter++;}
void dec() {counter--;}
}
public class MyThreadSafeProxy implements IMyObject {
private IMyObject realObject;
public MyThreadSafeProxy(IMyObject realObject) {
this.realObject = realObject;
}
@Override
public synchronized void inc() {
realObject.inc();
}
@Override
public syncrhonized void dec() {
realObject.dec();
}
}
Вместо хранения MyObject
-s вы можете обернуть их в MyThreadSafeProxy
Возможно также создать такой прокси автоматически: см. cglib framework или Dynami c Proxy (java .lang.Proxy class)
Исходя из моего опыта, вариант 1 предпочтителен, если только объекты, с которыми вы работаете, не слишком дороги, поэтому, если в пуле N потоков, вы не сможете реально поддерживать N объектов в памяти.