My task was to deal with problem of 5 eating thinkers. Each of them can eat only 10 times. Solution should base on Semaphore. I almost solved the task and output was correct when I simply used println for showing state of each thinker. But there is additional point to store those states in some sort of collection. And somehow I can't make it work. Now my Vector stores only first iteration of loop. What am I doing wrong ? Vector is static so it should work ok.
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]);
}
}
}
Output i should get :
1202393057117 1 OOOOO Thinker 1 is thinking 1202393057117 2 OOOOO Thinker 3 is thinking 1202393057118 3 OOOOO Thinker 0 is thinking 1202393057118 4 OOOOO Thinker 2 is thinking 1202393057118 5 OOOOO Thinker 4 is thinking 1202393057118 6 OOOOO Thinker 0 is hungry and is trying to pick up his chopsticks 1202393057119 7 lOOOO Thinker 0 is eating 1202393057119 8 OOOOO Thinker 0 finished eating 1202393057119 9 OOOOO Thinker 0 is thinking 1202393057119 10 OOOOO Thinker 0 is hungry and is trying to pick up his chopsticks 1202393057126 11 lOOOO Thinker 0 is eating 1202393057126 12 OOOOO Thinker 0 finished eatin开发者_JAVA百科gLet the Thinkers finish their meal before trying to display the states.
...
/* 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;
}
}
...
Your main method exits before the any/all of the Threads do their thing, it does not wait for them.
I've had to deal with a similar problem on several occasions, and I'm a big fan of CountDownLatch
. I'll provide an example how it can help, not saying this is the only/right way.
In this particular example, you could define:
private static CountDownLatch latch;
In your main, instantiate it with the number of threads you are using:
latch = new CountDownLatch(N);
Right before your threads' run() finishes, do:
latch.countDown();
Again, in your main, before trying to print the vector's contents:
latch.await();
(deal with InterruptedException as you best see fit).
The latch.await()
will block your main thread until all of the other threads are done, and you'll have your states recorded.
More: http://java.sun.com/javase/6/docs/api/java/util/concurrent/CountDownLatch.html
精彩评论