我的任务是处理5个吃思想家的问题。他们每人只能吃10次。解决方案应该基于Semaphore。当我简单地使用println显示每个思想家的状态时,我几乎解决了任务和输出是正确的。但还有一点是将这些状态存储在某种集合中。不知怎的,我无法让它发挥作用。现在我的Vector只存储了循环的第一次迭代。我究竟做错了什么 ?矢量是静态的,所以它应该可以正常工作。
import java.util.concurrent.Semaphore;
import java.util.Random;
import java.util.Vector;
public class Thinker extends Thread
{
private static final Random rand = new Random();
private static int event=0;
private int id;
private Semaphore sem;
private static Vector<Object[]> vector = new Vector<Object[]>();
public Thinker(int i, Semaphore s)
{
id = i;
sem = s;
}
private void busy()
{
try
{
sleep(rand.nextInt(1000));
} catch (InterruptedException e){}
}
private void thinking()
{
String str = "Thinker " + id + " is thinking";
vector.add( this.addToObject(System.currentTimeMillis(), event , str) );
event++;
busy();
}
private void eating()
{
String str ="Thinker " + id + " is hungry and is trying to pick up his chopsticks";
vector.add( this.addToObject(System.currentTimeMillis(), event , str) );
event++;
busy();
str = "Thinker " + id + " is eating";
vector.add( this.addToObject(System.currentTimeMillis(), event , str) );
event++;
busy();
str = "Thinker" + id + " finished eating, and puts away his chopsticks";
vector.add( this.addToObject(System.currentTimeMillis(), event , str) );
event++;
}
private Object[] addToObject(long t, int i,String s ){
Object[] o = new Object[4];
o[3] = s;
o[2] = i;
o[1] = "00000";
o[0] = t;
return o;
}
@Override
public void run()
{
for (int i = 0; i < 10; ++i)
{
thinking();
try
{
sem.acquire();
} catch (InterruptedException e){}
eating();
sem.release();
}
}
public static void main(String[] args)
{
final int N = 5;
Semaphore sem = new Semaphore(N, true);
Thinker[] thinker = new Thinker[N];
for (int i = 0; i < N; i++)
{
thinker[i] = new Thinker(i, sem);
thinker[i].start();
}
System.out.println("vctr size; "+vector.size());
for (int i = 0; i < vector.size(); i++) {
System.out.println();
Object[] o = vector.get(i);
System.out.printf("%d %d %s %s\n", o[0], o[2], o[1], o[3]);
}
}
}
输出我应该得到:
1202393057117 1OOOO思想家1正在思考
1202393057117 2 OOOOO思想家3正在思考
1202393057118 3OOOO思想家0正在思考
1202393057118 4OOOO思想家2正在思考
1202393057118 5 OOOOO思想家4正在思考
1202393057118 6 OOOOO Thinker 0很饿,正试图拿起他的筷子
1202393057119 7 lOOOO思想家0正在吃着
1202393057119 8 OOOOO思想家0吃完了
1202393057119 9 OOOOO思想家0正在思考
1202393057119 10 OOOOO Thinker 0很饿,正试图拿起他的筷子
1202393057126 11 lOOOO思想家0正在吃香
1202393057126 12 OOOOO Thinker 0吃完了
答案 0 :(得分:0)
你的主要方法在任何/所有线程执行之前退出,它不会等待它们。
我必须多次处理类似的问题,而且我是CountDownLatch
的忠实粉丝。我将举例说明它是如何提供帮助的,而不是说这是唯一/正确的方式。
在此特定示例中,您可以定义:
private static CountDownLatch latch;
在您的主体中,使用您正在使用的线程数来实例化它:
latch = new CountDownLatch(N);
在线程'run()完成之前,执行:
latch.countDown();
再次,在您的主要内容中,在尝试打印矢量的内容之前:
latch.await();
(处理InterruptedException,因为你认为合适)。
latch.await()
将阻止你的主线程,直到完成所有其他线程,并且你将记录你的状态。
更多:http://java.sun.com/javase/6/docs/api/java/util/concurrent/CountDownLatch.html
答案 1 :(得分:0)
让思想家在尝试展示各州之前完成他们的用餐。
...
/* Start the thinkers... */
for (int i = 0; i < N; i++) {
thinker[i] = new Thinker(i, sem);
thinker[i].start();
}
/* Wait for them to finish... */
for (int i = 0; i < N; i++) {
try {
thinker[i].join();
} catch(InterruptedException ex) {
return;
}
}
...