一种方法是使用锁(请查看java.util.concurrent.locks包),但我首先要考虑是否可以总体上改进该方法,例如使用无锁算法等
另一种方法是在共享库上使用同步方法/块.但是,这一切都取决于您实际要实现的目标.
使用同步块的示例:
T1:
while(...) {
synchronized( SomeClass.class ) {
doWork();
}
}
T2:
while(...) {
doWork();
synchronized( SomeClass.class ) {
update();
}
}
在这里,您将在Class< SomeClass>的同一实例上进行同步.只要您使用相同的类加载器,它就会起作用.
请记住,您应该使同步块尽可能小,以免添加不必要的块.
除此之外,请注意,T1中的同步块可能使T2很难在两次迭代之间中断.但是,问题在于为什么要这样设计.
编辑
作为同步整个doWork()调用的替代方法,您可能需要考虑实际需要同步的内容.
例如,使用以下伪代码:
WorkResult doWork(SharedObject so) {
Data data = so.loadData();
WorkResult wr = doSomeLengthyWork(data);
return wr;
}
void update(WorkResult wr, SharedObject so) {
so.updateFromWorkResult( wr );
}
如果您的情况是这样,则可以仅同步对so.loadData()和so.updateFromWorkResult()的调用,并让冗长的操作处理so.loadData()提供的数据的副本.
编辑2:
或者,您可以使用ReadWriteLock实现:
T1:
while(...) {
Lock readlock = readWriteLock.readLock();
readlock.lock();
doWork();
readlock.unlock();
}
T2:
while(...) {
doWork();
Lock writelock= readWriteLock.writeLock();
writelock.lock();
update();
writelock.unlock();
}
请注意,为简单起见,我省略了异常处理等.
您在这里基本上要做的是在工作期间获取读锁定,而在更新时获取写锁定.除非有一个写锁(允许多个读锁),否则多个线程可以并行工作,并且更新将一直等到所有读锁都被释放.为此,您可以在公平模式下使用ReentrantReadWriteLock,它应按请求的顺序发出锁,即,当T1仍在读取时T2要求锁时,尽管T1立即再次要求锁,但它仍将获得锁. .