试图处理具有两个不同线程的Order对象列表,但遇到以下异常:
Exception in thread "Thread 1" java.lang.IndexOutOfBoundsException: Index: 4, Size: 4
at java.util.ArrayList.rangeCheck(Unknown Source)
at java.util.ArrayList.get(Unknown Source)
at TaskThread.run(PrintOrder_Priority.java:193)
at java.lang.Thread.run(Unknown Source)
Thread 1:Processing Order234,7
Thread 2:Processing Order235,6
Thread 1:Processing Order237,5
Thread 2:Processing Order236,4
我刚刚省略了Order类的详细信息,其中包含诸如id
和priority
之类的字段。我已经根据订单的优先级对订单列表进行了排序,并希望处理订单。
class TaskThread implements Runnable
{
List<Order> orderList;
static volatile int i=0;
Semaphore sem1;
Semaphore sem2;
TaskThread(List<Order> orderList,Semaphore sem1,Semaphore sem2)
{
this.orderList=orderList;
this.sem1=sem1;
this.sem2=sem2;
}
@Override
public void run()
{
for(;i<orderList.size();)
{
try
{
sem1.acquire();
orderList.get(i).ProcessOrder();
i++;
sem2.release();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
main
方法的内容:
Semaphore sem1 = new Semaphore(1);
Semaphore sem2 = new Semaphore(0);
Thread T1 = new Thread(new TaskThread(aList,sem1,sem2));
Thread T2 = new Thread(new TaskThread(aList,sem2,sem1));
T1.setName("Thread 1");
T1.start();
T2.setName("Thread 2");
T2.start();
答案 0 :(得分:1)
您的问题是,获取信号量之前要检查大小条件,当获取信号量时,i的值与您在条件中检查的值不同:
Thread1: Thread2:
condition check: i ==0; OK; condition check: i ==0; OK;
acquire sem1: waiting form sem2
process i =0; waiting form sem2
increase i to 1; waiting form sem2
release sem2; you acquire sem2 but i ==1;
condition check: i ==1; OK; process i =1;
waiting form sem1 increase i to 2;
waiting form sem1 release sem1;
acquire sem1 but i ==2; condition check: i ==2; OK;
process i =2; waiting form sem2
increase i to 3; waiting form sem2
release sem2; you acquire sem2 but i ==3;
condition check: i ==3; OK; process i =3;
waiting form sem1 increase i to 4;
waiting form sem1 release sem1;
acquire sem1 but i==4!!!!!!
you call ->> orderList.get(i) -> exception thrown
如果要使用解决方案,最简单的解决方法是在购买显示器后也添加支票
sem1.acquire();
if(i >= orderList.size()){
break;
}
答案 1 :(得分:0)
https://www.baeldung.com/java-even-odd-numbers-with-2-threads
有意更新此内容而忘记了。这个例子似乎显示了两个线程在信号量上交替变化,就像您以前那样。他们没有共享变量,但是很接近。
答案 2 :(得分:0)
可能是volatile关键字。根据此article,volatile提供了“之前发生”的保证,但没有更多。也许尝试AtomicLong