我有一个简单的要求,即在两个服务之间共享一个资源(让我们说一个链表):一个向其添加元素,另一个计算它的统计信息。我想在java中使用重入锁。我想出了以下解决方案。
有没有比这更好的解决方案?
public class SharedServer {
private List<Integer> numbers;
public SharedServer(List<Integer> numbers){
this.numbers = numbers;
}
Lock lock = new ReentrantLock();
public void addElements(int element){
try{
Thread.sleep(100);
System.out.println("Adding element");
numbers.add(element);
System.out.println("Added : "+element);
}catch(InterruptedException e){
System.out.println("Interrupted while adding elements");
}
}
public void caluclateStatistics(){
try{
Thread.sleep(200);
System.out.println("calculating statistics");
System.out.println("Min : "+Collections.min(numbers)+" Max : "+Collections.max(numbers)+" Avg : "+(Collections.min(numbers)+Collections.max(numbers))/numbers.size());
}catch(InterruptedException e){
System.out.println("Interrupted while performing calculations on elements");
}
}
}
public class StatisticsCalculator implements Runnable {
private SharedServer sharedServer;
public StatisticsCalculator(SharedServer sharedServer){
this.sharedServer = sharedServer;
}
@Override
public void run() {
System.out.println("Calculator");
boolean acquired = false;
try {
acquired = sharedServer.lock.tryLock(300,TimeUnit.MILLISECONDS);
sharedServer.caluclateStatistics();
} catch (InterruptedException e) {
System.out.println("COULD NOT ACQUIRE CALCULATOR");
e.printStackTrace();
}finally{
if(acquired){
sharedServer.lock.unlock();
System.out.println("Calculator released");
}
}
}
}
public class ElementAdder implements Runnable {
private SharedServer sharedServer;
public ElementAdder(SharedServer sharedServer){
this.sharedServer = sharedServer;
}
@Override
public void run() {
System.out.println("Adder");
boolean acquired = false;
try {
acquired = sharedServer.lock.tryLock(300,TimeUnit.MILLISECONDS);
sharedServer.addElements(ThreadLocalRandom.current().nextInt(1, 1000));
} catch (InterruptedException e) {
System.out.println("COULD NOT ACQUIRE ADDER");
e.printStackTrace();
}finally{
if(acquired){
sharedServer.lock.unlock();
System.out.println("Adder released");
}
}
}
}
public class Main {
public static void main(String[] args) {
List<Integer> ints = new ArrayList<>();
SharedServer sharedService = new SharedServer(ints);
ExecutorService executorService1 = Executors.newCachedThreadPool();
ExecutorService executorService2 = Executors.newCachedThreadPool();
for(int index=0; index<50;index++){
executorService1.submit(new ElementAdder(sharedService));
}
for(int index=0; index<50;index++){
executorService2.submit(new StatisticsCalculator(sharedService));
}
executorService1.shutdown();
executorService2.shutdown();
}
}
只有强制性的事情是不应该错过任何电话(加法器或计算器)。
答案 0 :(得分:1)
您是否有特定理由使用折返锁定?您的calculateStatistics()
方法是否执行IO? (不确定你的例子是否过于简化)
通常,synchronized
在概念上更简单,更容易正确,因此除非您需要超时(或ReentrantLock
的其他功能),否则您可能只想使用synchronized
。