Thread ordering

Hi all

I have a little program that uses a barrier that makes a number of threads wait until a threshold has been reached.

When this happens those threads are released and thereafter all threads pass.

See below.

publicclass BarrierDemo{

staticint noOfThreads = 20;

staticint barrierSize = 10;

staticint interval = 500;

//static Threads[] threads;

static Barrier barrier;

publicstaticvoid main(String args[]){

System.out.println("Number of threads = "+noOfThreads);

System.out.println("Barrier Size = "+barrierSize);

System.out.println("Interval = "+interval);

barrier =new Barrier(barrierSize);

for (int i=0 ; i<noOfThreads ; i++){

new Threads(barrier, i).start();

try{

Thread.sleep(interval);

}

catch (java.lang.InterruptedException e){

System.out.println("sleep interupted (yawn :o).");

System.out.println(" Exception - "+e+".");

}

}

}

privatestaticclass Threadsextends Thread{

Barrier barrier;

int threadNo;

Threads(Barrier b,int i){

barrier = b;

threadNo = i;

}

publicvoid run(){

try{

System.out.println("Thread "+ threadNo +" is waiting at the barrier");

barrier.barrierControl();

System.out.println("Thread "+ threadNo +" passed the barrier");

}

catch (java.lang.InterruptedException e){

System.out.println(e);

}

}

}

privatestaticclass Barrier{

privateint count = 0;

privateint barrierSize;

Barrier(int i){

barrierSize = i;

}

synchronizedvoid barrierControl()throws InterruptedException{

count++;

while (count ><= barrierSize){

wait();

}

notifyAll();

}

}

}

The output should be like this..

Number of threads = 20

Barrier Size = 10

Interval = 500

Thread 0 is waiting at the barrier

Thread 1 is waiting at the barrier

Thread 2 is waiting at the barrier

Thread 3 is waiting at the barrier

Thread 4 is waiting at the barrier

Thread 5 is waiting at the barrier

Thread 6 is waiting at the barrier

Thread 7 is waiting at the barrier

Thread 8 is waiting at the barrier

Thread 9 is waiting at the barrier

Thread 10 is waiting at the barrier

Thread 0 passed the barrier

Thread 1 passed the barrier

Thread 2 passed the barrier

Thread 3 passed the barrier

Thread 4 passed the barrier

Thread 5 passed the barrier

Thread 6 passed the barrier

Thread 7 passed the barrier

Thread 8 passed the barrier

Thread 9 passed the barrier

Thread 10 passed the barrier

Thread 11 is waiting at the barrier

Thread 11 passed the barrier... etc.

It usually does this. However, the ordering is not guaranteed. I thought about using an array so that I could find each specific thread in turn and notify() something like this...

publicclass BarrierDemo{

staticint noOfThreads = 20;

staticint barrierSize = 10;

staticint interval = 500;

static Threads[] threads;

static Barrier barrier;

publicstaticvoid main(String args[]){

System.out.println("Number of threads = "+noOfThreads);

System.out.println("Barrier Size = "+barrierSize);

System.out.println("Interval = "+interval);

threads =new Threads[noOfThreads];

barrier =new Barrier(barrierSize);

for (int i=0 ; i<noOfThreads ; i++){

threads[i] =new Threads(barrier, i);

threads[i].start();

//new Threads(barrier, i).start();

try{

Thread.sleep(interval);

}

catch (java.lang.InterruptedException e){

System.out.println("sleep interupted (yawn :o).");

System.out.println(" Exception - "+e+".");

}

}

}

//private static void notifications(int t) {

//threads[t].notify();

//}

privatestaticclass Threadsextends Thread{

Barrier barrier;

int threadNo;

Threads(Barrier b,int i){

barrier = b;

threadNo = i;

}

publicvoid run(){

try{

System.out.println("Thread "+ threadNo +" is waiting at the barrier");

barrier.barrierControl(threadNo);

System.out.println("Thread "+ threadNo +" passed the barrier");

}

catch (java.lang.InterruptedException e){

System.out.println(e);

}

}

}

privatestaticclass Barrier{

privateint count = 0;

privateint barrierSize;

Barrier(int i){

barrierSize = i;

}

synchronizedvoid barrierControl(int threadID)throws InterruptedException{//passports please :o)

count++;

while (count ><= barrierSize){

wait();

}

for (int i=0 ; i<noOfThreads ; i++){

threads[i].notify();

//BarrierDemo.notifications(i);

}

//notifyAll();

}

}

}

but that doesn't work.

The output is then like this;

...

... Thread 9 is waiting at the barrier

Thread 10 is waiting at the barrier

Exception in thread "Thread-10" java.lang.IllegalMonitorStateException: current

thread not owner... etc.

I also thought about changing their priorities but from what I have read this does not guarantee the order either.

Can anyone advise me how I can strictly enforce the order ?

Cheers>

[10606 byte] By [turpierga] at [2007-11-26 18:17:36]
# 1
not got time to look to closly at the moment, but why are all your classes static? you should look the meaning of static before using it so losely, seperate stuff into seperate classes outise of Main() to avoid static problems.
grilleda at 2007-7-9 5:51:13 > top of Java-index,Java Essentials,Java Programming...
# 2

Thread scheduling doesn't guarantee a lot. Basically it just guarantees that all of your threads will have the chance to run at some time, and that usually it's rather fair (depending on priority, of course). Everything else is implementation dependent. Why do you need a specific order of responses? If you need it, why do all these threads wait() on the same object?

JoachimSauera at 2007-7-9 5:51:13 > top of Java-index,Java Essentials,Java Programming...
# 3

Hi

"Why do you need a specific order of responses?" Well the easy answer is, 'because someone asked me to'. I realise that normally we let the threads run as the scheduler decides. I guess this is to help me figure out what I can and can't do with threads.

Somebody did suggest I could make them check how many had preceded them using a count and if the wrong number had been through then wait() (sorry should have said sleep) until it was right.

Why I didn't think of that, I don't know !!

I take note of the mention of the use of static. I will go away and ponder whether having some object other than a thread would be useful.

Cheers

Message was edited by: turpierg

turpierg

turpierga at 2007-7-9 5:51:13 > top of Java-index,Java Essentials,Java Programming...
# 4

Threading is designed to allow for asynchronous, independent, concurrent units of work.

It looks to me like you want to guarantee order-of-execution, and you also want to guarantee that one unit-of-work has completed in its entirety before the next one starts.

The more control you want over execution, the less likely it is that threads are the right answer. The exercise you're engaging in seems quite appropriate, if the "person" asking you to do it means to drive that point home. The more you find yourself squirming to work around the natural behavior of any given abstraction, the more likely it is that you've picked the wrong abstraction for your problem domain.

Grant

ggaineya at 2007-7-9 5:51:13 > top of Java-index,Java Essentials,Java Programming...
# 5

Hi

Well I got it working with a count on how many passed the barrier and then a test that each thread goes through (the threads are numbered) to see if they were next and if they are the one trying but shouldn't be next , then they are put to sleep for a very short while.

Looking back it just makes me look at what options are available and use them. Got very bogged down in Semaphores but I need to understand them. So the time was not wasted.

Cheers

turpierga at 2007-7-9 5:51:13 > top of Java-index,Java Essentials,Java Programming...
# 6

I think post #5 is very much to be taken to heart. Executing the Thread from main is not relevant; however, making the Thread subclass static is not a good idea. Going through all the trouble seems counterproductive. If all you want to do is garrantee that the processing is ordered, than using multiple Threads is probably not the best way to go about it. Did you end up with something like this:

public class MainClass {

private static int threadNo;

public static void main(String[] argv) {

for (int i = 11; i > 0; i-- )

new MainClass().new MyThread(i).start();

}

private class MyThread extends Thread {

int no;

public MyThread(int _no) {

no = _no;

}

public void run() {

while ( threadNo != (no - 1) ) {

System.out.println("MyThread (waiting) threadNo #"+threadNo+" no #"+no);

try {

Thread.sleep(500);

}

catch(InterruptedException ie) {

System.out.println("ie: "+ie);

}

}

threadNo++;

System.out.println("MyThread (not waiting) threadNo #"+threadNo+" no #"+no);

}

}

}

?

abillconsla at 2007-7-9 5:51:13 > top of Java-index,Java Essentials,Java Programming...
# 7

Hi

I found out later that the task was badly specified. Whereas I the output we were asked to acheive showed each thread coming through exactly in order, this was not required. All that was required was that those numbered up to the barrier size wait and then the first lot go through (up to and including the thread number equal to the barrierSize) then followed by all others (however many follow).

I was asked to look again at my solution using wait and notify.

My prog actually did what I was asked to do but I didn't realize that strict order throughout wasn't necessary!

Anyhow the Barrier class code ended up something like this.

private static class Barrier {

private int barrierSize;

Barrier(int i){

barrierSize = i;

}

synchronized void barrierControl(int t) throws InterruptedException{

if(t <= barrierSize){

wait();

notify();

}

if(t == barrierSize +1){

notify();

wait();

};

}

}

Which was acceptable (not sure if I eventually used notifyAll( ) though). I will have the oportunity to discuss over the phone so I can get a better idea of what I should have done.

NotifyAll( ) was expected, to tell the rest to go through but I used notify() ( I was still trying to keep the exact order one-by-one).

Thanks for your interest.

:o)

turpierga at 2007-7-9 5:51:13 > top of Java-index,Java Essentials,Java Programming...
# 8

You could also try something like this:

public class MainClass {

private static int threadCount;

private static MyThread[] threads = new MyThread[10];

public static void main(String[] argv) {

for (int i = threads.length - 1; i >= 0; i-- ) {

threads[i] = new MainClass().new MyThread(i);

threads[i].start();

}

}

private class MyThread extends Thread {

private int threadNumber;

public MyThread(int _threadNumber) {

threadNumber = _threadNumber;

}

public synchronized void run() {

while ( threadCount != threadNumber ) {

System.out.println("MyThread ( ...waiting)"

+" threadCount #"+threadCount

+" threadNumber #"+threadNumber);

try {

wait(5000);

}

catch(InterruptedException ie) {

System.out.println("ie: "+ie);

}

}

System.out.println("MyThread (not waiting)"

+" threadCount #"+threadCount

+" threadNumber #"+threadNumber);

try {

Thread.sleep(10000);

System.out.println("MyThread, theadNumber #"

+threadNumber+", back from sleep");

}

catch(InterruptedException ie2) {

System.out.println("ie2: "+ie2);

}

threadCount++;

notifyAll();

}

}

}

You do not need the array.

~Bill

abillconsla at 2007-7-9 5:51:13 > top of Java-index,Java Essentials,Java Programming...