eire_ireland
asked on
Thread priorities?
There are two threads that have been started. Thread one is executing, when this thread encounters a certain line of code pause execution until the other thread completes execution, then finish execution of the thread that has been paused. Is there any way of doing this?
Use the join() method to do it.
You can do this using the wait-notify mechanism (see Sun thread tutorial) but i'm skeptical you need this in your project...
ASKER
Well I think I do, because both threads are calling the same function. The return value of the function depends on the second thread that has started. So I want the first thread to wait until the second thread has called the function before I call the function in the first thread.
Take a look here and tell me if it helps: http://javaalmanac.com/egs/java.lang/IfStopped.html otherwise I will try to post some sample code.
ASKER
In using the join() how do I target the thread that I want to wait for?
If the thread that does the reading is called readingThread then when you find the line just do:
readingThread.join();
and this should work. It should wait for the other thread to finish before it goes on again.
readingThread.join();
and this should work. It should wait for the other thread to finish before it goes on again.
ASKER
This is what I want to do
thread one
wait until thread two has got return value then
get return value from function
thread two
get return value from function
thread one
wait until thread two has got return value then
get return value from function
thread two
get return value from function
Alternative you can go with CEHJ's solution. Have the reading thread wait and when then other thread finishes call notifyAll and this should get the reading thread started again.
I suggest you use join though, after all that's what it is here for :)
I suggest you use join though, after all that's what it is here for :)
ok in a nutshell this could be:
Thread t1 = new Thread();
Thread t2 = new Thread();
t1.start();
t2.start();
...
if (lineFound)
{
t1.join();
}
About reading the return value. YOu can have an instance variable (synchronize it) that will be set to a value when thread two (t2)finishes... after that t1 can read it and proceed normally.
Thread t1 = new Thread();
Thread t2 = new Thread();
t1.start();
t2.start();
...
if (lineFound)
{
t1.join();
}
About reading the return value. YOu can have an instance variable (synchronize it) that will be set to a value when thread two (t2)finishes... after that t1 can read it and proceed normally.
ASKER
The thread im waiting for to finish is the second thread so the name of that thread is not set until it begins, how can I use the join method in the first thread?
>>This is what I want to do...
Why? Why not just wait until the process has finished and then draw the necessary conclusions?
Why? Why not just wait until the process has finished and then draw the necessary conclusions?
If you want to wait for the second thread to finish then you need to call join on the second thread. join() always waits for the calling thread to finish before going further.
(assuming your current project)
Player1 sends "rock" and its name
Player2 sends "scissors" and its name
Having received two messages, server declares Player1 the winner
Player1 sends "rock" and its name
Player2 sends "scissors" and its name
Having received two messages, server declares Player1 the winner
ASKER
I did try something like that CEHZ but it didnt work, I think the join way might work but its not recognising my thread names. Im using setName to name the thread and nameofthread.join() but its throwing an error.
eire_ireland do you want the second thread to start simultaneously with the first thread or after the first thread has joined?
If you do t1.join() then the first thread will finish what it's doing and then you can start the second one. If you start both threads at the same time and you use join() you run the risk of one thread finishing before join is ever getting called so join() will simply return.
I have written a very quick and simpl example using wait and notify as suggestedoriginally by CEHJ. I adapted the Thread example of the java threa tutorial, maybe you will be able to modify it to obtain what you want. The programme simply runs two threads "Blue" and "Red" and at some point the Blue thread waits for the Red thread to finish. The Red thread does a dummy calculation of a variable (I call it "result") and then it sets it to the result of a multiplication. The Blue thread then goes on and access it and displays it on the screen.
class Blue extends Thread {
private ThreadSwitch ts;
public Blue(String str, ThreadSwitch ts) {
super(str);
this.ts=ts;
}
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(i + " " + getName());
try {
if (i==5)
{
System.out.println(getName () + " is waiting till other thread finishes");
ts.lock();
}
sleep((long)(Math.random() * 2000));
} catch (InterruptedException e) {}
}
System.out.println("DONE! " + getName());
System.out.println("Result is: " + ts.getInt());
}
}
class Red extends Thread {
private ThreadSwitch ts;
public Red(String str, ThreadSwitch ts) {
super(str);
this.ts=ts;
}
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(i + " " + getName());
try {
sleep((long)(Math.random() * 2000));
} catch (InterruptedException e) {}
}
System.out.println("DONE! " + getName());
ts.setInt(6*3);
}
}
class ThreadSwitch
{
public int result = 0;
public synchronized void lock()
{
while (result == 0)
{
try
{
wait();
}
catch(InterruptedException ie)
{
System.err.println(ie);
}
}
notify();
}
public synchronized void setInt(int i)
{
notify();
result = i;
}
public synchronized int getInt()
{
notify();
return result;
}
}
public class ThreadTest {
public static void main (String[] args) {
ThreadSwitch ts = new ThreadSwitch();
Thread t1 = new Blue("Blue", ts);
Thread t2 = new Red("Red", ts);
t1.start();
t2.start();
}
}
If you do t1.join() then the first thread will finish what it's doing and then you can start the second one. If you start both threads at the same time and you use join() you run the risk of one thread finishing before join is ever getting called so join() will simply return.
I have written a very quick and simpl example using wait and notify as suggestedoriginally by CEHJ. I adapted the Thread example of the java threa tutorial, maybe you will be able to modify it to obtain what you want. The programme simply runs two threads "Blue" and "Red" and at some point the Blue thread waits for the Red thread to finish. The Red thread does a dummy calculation of a variable (I call it "result") and then it sets it to the result of a multiplication. The Blue thread then goes on and access it and displays it on the screen.
class Blue extends Thread {
private ThreadSwitch ts;
public Blue(String str, ThreadSwitch ts) {
super(str);
this.ts=ts;
}
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(i + " " + getName());
try {
if (i==5)
{
System.out.println(getName
ts.lock();
}
sleep((long)(Math.random()
} catch (InterruptedException e) {}
}
System.out.println("DONE! " + getName());
System.out.println("Result
}
}
class Red extends Thread {
private ThreadSwitch ts;
public Red(String str, ThreadSwitch ts) {
super(str);
this.ts=ts;
}
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(i + " " + getName());
try {
sleep((long)(Math.random()
} catch (InterruptedException e) {}
}
System.out.println("DONE! " + getName());
ts.setInt(6*3);
}
}
class ThreadSwitch
{
public int result = 0;
public synchronized void lock()
{
while (result == 0)
{
try
{
wait();
}
catch(InterruptedException
{
System.err.println(ie);
}
}
notify();
}
public synchronized void setInt(int i)
{
notify();
result = i;
}
public synchronized int getInt()
{
notify();
return result;
}
}
public class ThreadTest {
public static void main (String[] args) {
ThreadSwitch ts = new ThreadSwitch();
Thread t1 = new Blue("Blue", ts);
Thread t2 = new Red("Red", ts);
t1.start();
t2.start();
}
}
The ThreadSwitch class is the class that holds the lock on the "result" variable. Apart from that it is also used to set and get the value of the "result".
... also the getInt() method should't probably be synchronized :)
... and you obviously do not need the
while (result == 0)
{
loop in the lock() method.
while (result == 0)
{
loop in the lock() method.
> loop in the lock() method.
meant block of code in the lock method. Simply do:
public synchronized void lock()
{
try
{
wait();
}
catch(Interrupted Exception ie)
{
System.err.println(ie) ;
}
notify();
}
meant block of code in the lock method. Simply do:
public synchronized void lock()
{
try
{
wait();
}
catch(Interrupted
{
System.err.println(ie)
}
notify();
}
ASKER
This is how im defining my threads. I cant really take a whole lot from the code you posted, I dont think its what i have in mind. This is of the code im using and Im trying to do is commented.
public FirstClient(Socket socket) {
this.socket = socket;
start();
}
public void run()
{ try
{
//I want the thread to go this far and then stop until the second thread (SecondClient below) fully executes.
if(num == 1){
output = new PrintWriter(new OutputStreamWriter(socket. getOutputS tream()), true);
output.println("You have lost");
public SecondClient(Socket socket) {
this.socket = socket;
start();
}
public void run()
{ try
{
if(num == 1){
output = new PrintWriter(new OutputStreamWriter(socket. getOutputS tream()), true);
output.println("You have won");
public FirstClient(Socket socket) {
this.socket = socket;
start();
}
public void run()
{ try
{
//I want the thread to go this far and then stop until the second thread (SecondClient below) fully executes.
if(num == 1){
output = new PrintWriter(new OutputStreamWriter(socket.
output.println("You have lost");
public SecondClient(Socket socket) {
this.socket = socket;
start();
}
public void run()
{ try
{
if(num == 1){
output = new PrintWriter(new OutputStreamWriter(socket.
output.println("You have won");
>>I did try something like that CEHZ but it didnt work
It's not generally a good idea, if you can't get something simple working, to try something more complex in the hope that it'll fix things.
I see no reason to do anything other than wait until the two players have taken their turns and then inform them of the outcome. There is no reason for synchronization of threads in the way you imagine.
It's not generally a good idea, if you can't get something simple working, to try something more complex in the hope that it'll fix things.
I see no reason to do anything other than wait until the two players have taken their turns and then inform them of the outcome. There is no reason for synchronization of threads in the way you imagine.
You do not need to take a whole lot from the code I posted, just the principle of it, how to make a thread wait while another one is executing. Just run my code (copy/paste it), see if it is something you need and then you can adjust the principles in your application.
> This is of the code im using and Im trying to do is commented.
In that case join() won't help (unless you handle clients a little differently).
You need to use wait()/notify() in your threads similiar to the example girionis has posted above. Where your client thread would do something like:
- read value from user
- wait
- send outcome
And in the server notify clients once values recieved from both users
In that case join() won't help (unless you handle clients a little differently).
You need to use wait()/notify() in your threads similiar to the example girionis has posted above. Where your client thread would do something like:
- read value from user
- wait
- send outcome
And in the server notify clients once values recieved from both users
ASKER
Generally maybe, but this way ive output going to the second client informing of the outcome. returnval(a var in the code below - num in the previous post is returnval) is initially set to zero when the firsts client calls it. But this value may be changed by the second client which is why I want to call the below function in the first client after the second client executes. I can see no reason why this wont work if a method is put forward that does what im asking?
public int StoreChoice(String Choise1, int flag, int thr)
{
int returnval = 0;
if (thr == 2){
Choisetwo = Choise1;
display.append("\n\n First Player to connect sent" +Choiseone);
display.append("\n\n Second Player to connect sent" +Choisetwo);
if(Choiseone.equals("Rock" ) && Choisetwo.equals("Paper")) {
returnval = 1;
display.append("\n\nIn checking");
return(returnval);
}
public int StoreChoice(String Choise1, int flag, int thr)
{
int returnval = 0;
if (thr == 2){
Choisetwo = Choise1;
display.append("\n\n First Player to connect sent" +Choiseone);
display.append("\n\n Second Player to connect sent" +Choisetwo);
if(Choiseone.equals("Rock"
returnval = 1;
display.append("\n\nIn checking");
return(returnval);
}
your problem is that your client threads need to wait for the all input to become available, and then by notified when it is available so they can proceed.
ASKER
I was trying that earlier and came up with this but the display methods didnt get executed?
public class Serverz extends Frame
{
String Choiseone;//declared gloablly
String Choisetwo;//declared globally
else if (ClientsConnected == 1)
new FirstClient(serve.accept() );
else if (ClientsConnected == 2){
new SecondClient(serve.accept( ));
display.append("\n\n First Player to connect sent" +Choiseone);
display.append("\n\n Second Player to connect sent" +Choisetwo);
//Choiseone and Choisetwo got here
public class Serverz extends Frame
{
String Choiseone;//declared gloablly
String Choisetwo;//declared globally
else if (ClientsConnected == 1)
new FirstClient(serve.accept()
else if (ClientsConnected == 2){
new SecondClient(serve.accept(
display.append("\n\n First Player to connect sent" +Choiseone);
display.append("\n\n Second Player to connect sent" +Choisetwo);
//Choiseone and Choisetwo got here
Perhaps, for clarification, you can tell us, without using any technical language, what you want the sequence of events to be, message-wise, among the participants?
Here's an outline of what is needed:
You client thread needs to do something like this (where server is a reference to Serverz instance that started the thread):
public void run()
{
// read input from user
server.setResult(answer);
String result = server.getResult();
// send result to server
}
For a single game your server then just needs to start the two threads:
a = new FirstClient(serve.accept() );
b = new SecondClient(serve.accept( ));
public void setResult(String result)
{
// store results
if (input recieved from both clients)
{
// all input recieved, so notify waiting thread
notifyAll();
}
else
{
// have not recieved input from other palyer so wait until it comes in
wait();
}
}
You client thread needs to do something like this (where server is a reference to Serverz instance that started the thread):
public void run()
{
// read input from user
server.setResult(answer);
String result = server.getResult();
// send result to server
}
For a single game your server then just needs to start the two threads:
a = new FirstClient(serve.accept()
b = new SecondClient(serve.accept(
public void setResult(String result)
{
// store results
if (input recieved from both clients)
{
// all input recieved, so notify waiting thread
notifyAll();
}
else
{
// have not recieved input from other palyer so wait until it comes in
wait();
}
}
ASKER
I think this could work but its throwing an error:
try{
FirstClient a = new FirstClient(serve.accept() );
SecondClient b = new SecondClient(serve.accept( ));
// wait for thread to finish
a.join();
b.join();
display.append("\n\n First Player to connect sent" +Choiseone);
display.append("\n\n Second Player to connect sent" +Choisetwo);
}
catch( IOException e )
{
e.printStackTrace() ;
}
C:\Documents and Settings\Adrian Ron\Desktop\Serverz.java:7 4: unreported exception java.lang.InterruptedExcep tion; must be caught or declared to be thrown
a.join();
^
C:\Documents and Settings\Adrian Ron\Desktop\Serverz.java:7 5: unreported exception java.lang.InterruptedExcep tion; must be caught or declared to be thrown
b.join();
^
try{
FirstClient a = new FirstClient(serve.accept()
SecondClient b = new SecondClient(serve.accept(
// wait for thread to finish
a.join();
b.join();
display.append("\n\n First Player to connect sent" +Choiseone);
display.append("\n\n Second Player to connect sent" +Choisetwo);
}
catch( IOException e )
{
e.printStackTrace() ;
}
C:\Documents and Settings\Adrian Ron\Desktop\Serverz.java:7
a.join();
^
C:\Documents and Settings\Adrian Ron\Desktop\Serverz.java:7
b.join();
^
Problem with using join() is that you don't get opportunity to send the result back to the client as the client thread would have alreay completed.
ASKER
Objects : this is code I got off you a few days ago for a different problem, I didnt use it then but it compiled fine, is there a difference?
Comment from objects
Date: 12/07/2003 01:06PM PST
Comment
> is there a way of waiting until the two threads have executed
yes, if thats what you want to do.
FirstClient a = new FirstClient(serve.accept() );
SecondClient b = new SecondClient(serve.accept( ));
// wait for thread to finish
a.join();
b.join();
Comment from objects
Date: 12/07/2003 01:06PM PST
Comment
> is there a way of waiting until the two threads have executed
yes, if thats what you want to do.
FirstClient a = new FirstClient(serve.accept()
SecondClient b = new SecondClient(serve.accept(
// wait for thread to finish
a.join();
b.join();
> I didnt use it then but it compiled fine, is there a difference?
The InterruptedException exception must have been being handled by that code block previously.
When I suggested that I was not aware you needed to return the result to client.
The InterruptedException exception must have been being handled by that code block previously.
When I suggested that I was not aware you needed to return the result to client.
ASKER
What am i doing wrong?
you're not handling the exception. you need to wrap the join's in a try/catch block.
ASKER
Ive tried this but its throwing the same error, could it be my jdk?
try{
a.join();
b.join();
}
catch( IOException e )
{
e.printStackTrace() ;
}
--------------------Config uration: j2sdk1.4.0_02 <Default>----------------- ---
C:\Documents and Settings\Adrian Ron\Desktop\Serverz.java:7 5: unreported exception java.lang.InterruptedExcep tion; must be caught or declared to be thrown
a.join();
^
C:\Documents and Settings\Adrian Ron\Desktop\Serverz.java:7 6: unreported exception java.lang.InterruptedExcep tion; must be caught or declared to be thrown
b.join();
^
C:\Documents and Settings\Adrian Ron\Desktop\Serverz.java:7 8: exception java.io.IOException is never thrown in body of corresponding try statement
catch( IOException e )
try{
a.join();
b.join();
}
catch( IOException e )
{
e.printStackTrace() ;
}
--------------------Config
C:\Documents and Settings\Adrian Ron\Desktop\Serverz.java:7
a.join();
^
C:\Documents and Settings\Adrian Ron\Desktop\Serverz.java:7
b.join();
^
C:\Documents and Settings\Adrian Ron\Desktop\Serverz.java:7
catch( IOException e )
you need to catch InterruptedException, instead of IOException
ASKER
thats it, cheers, its still not executing the code although, after the joins... Im closing input and output streams for each thread so the threads should be finishing up.
add some deug in your client thread to see where its up to.
ASKER
just something I noticed there, if im closing up each client thread after they have sent their choice how am I going to send the result (based on the choice) to each client?
>>
Player1 sends "rock" and its name
Player2 sends "scissors" and its name
Having received two messages, server declares Player1 the winner
>>
...sending the result on the appropriate socket, having saved them in a list.
Player1 sends "rock" and its name
Player2 sends "scissors" and its name
Having received two messages, server declares Player1 the winner
>>
...sending the result on the appropriate socket, having saved them in a list.
> how am I going to send the result (based on the choice) to each client?
that was mentioned above. thayts why join() is not approriate with your current architecture. Either use wait()/notify() as I outlined above, or move the code that returns the results to the client out of your clients run() emthod into it's own.
I'd suggest the wait/notify approach.
that was mentioned above. thayts why join() is not approriate with your current architecture. Either use wait()/notify() as I outlined above, or move the code that returns the results to the client out of your clients run() emthod into it's own.
I'd suggest the wait/notify approach.
ASKER
output and socket streams are not closing. Output sends a string to the server, iand socket is just a socket connection. any other way to close them?
there is a close() method.
ASKER
Im using the close method, but its not closing the streams
input.close(); //this is closing
output.close(); //not closing
socket.close(); //not closing
input.close(); //this is closing
output.close(); //not closing
socket.close(); //not closing
it should do, are you sure that code is being executed.
Add a debug println() call before it to check.
Add a debug println() call before it to check.
ASKER
The sockets werent closing in a try but now they are, moved the close statements:
//reading choice sent by client
readChoice = input.readLine();
display.append(readChoice) ;
output = new PrintWriter(new OutputStreamWriter(socket. getOutputS tream()), true);
num = StoreChoice(readChoice, 2 , 1 , 0 , "");
display.setText("\n\n Input");
input.close();
output.close();
display.append("\n\n Output");
socket.close();
display.append("\n\n Socket");
The following code from earlier now works
a.join();
b.join();
display.append("\n\n First Player to connect sent" +Choiseone);
display.append("\n\n Second Player to connect sent" +Choisetwo);
But the each of the clients goes into an infinite loop outputting null, is it ok to close the sockets like this?, the append commands output the correct values entered by the user.
//reading choice sent by client
readChoice = input.readLine();
display.append(readChoice)
output = new PrintWriter(new OutputStreamWriter(socket.
num = StoreChoice(readChoice, 2 , 1 , 0 , "");
display.setText("\n\n Input");
input.close();
output.close();
display.append("\n\n Output");
socket.close();
display.append("\n\n Socket");
The following code from earlier now works
a.join();
b.join();
display.append("\n\n First Player to connect sent" +Choiseone);
display.append("\n\n Second Player to connect sent" +Choisetwo);
But the each of the clients goes into an infinite loop outputting null, is it ok to close the sockets like this?, the append commands output the correct values entered by the user.
> each of the clients goes into an infinite loop outputting null
you need to determine why they are looping.
you need to determine why they are looping.
ASKER
This is why, im closing sockets in a while loop, a silly mistake, if I take the closing methods out of the while loop a compile error saying the statements are not reachable is thrown. If I put the closing methods into a "finally" they dont get executed. What can I do?
while (true)
{
//reading choice sent by client
readChoice = input.readLine();
display.append(readChoice) ;
output = new PrintWriter(new OutputStreamWriter(socket. getOutputS tream()), true);
//table.put(threadName, String);
addString(getName(), readChoice);
input.close();
display.setText("\n\n Input");
output.close();
display.append("\n\n Output");
socket.close();
display.append("\n\n Socket");
}
while (true)
{
//reading choice sent by client
readChoice = input.readLine();
display.append(readChoice)
output = new PrintWriter(new OutputStreamWriter(socket.
//table.put(threadName, String);
addString(getName(), readChoice);
input.close();
display.setText("\n\n Input");
output.close();
display.append("\n\n Output");
socket.close();
display.append("\n\n Socket");
}
> while (true)
Why are you looping forever?
Why are you looping forever?
ASKER
I should'nt be doin that, I think its fixed now anyway, just to do this:
Player1 sends "rock" and its name
Player2 sends "scissors" and its name
Having received two messages, server declares Player1 the winner
>>
...sending the result on the appropriate socket, having saved them in a list.
How do I save to a list, I know its another question, ill increase the points
Player1 sends "rock" and its name
Player2 sends "scissors" and its name
Having received two messages, server declares Player1 the winner
>>
...sending the result on the appropriate socket, having saved them in a list.
How do I save to a list, I know its another question, ill increase the points
Theres no need to save them in a list, (and not really appropriate either).
Just have each client remember the answer recieved, and the server can then get the answers directly from client instances.
Just have each client remember the answer recieved, and the server can then get the answers directly from client instances.
ASKER
Could you elaborate a little , im fairly new to java....probably obvious
Add a member variable to your client thread class and store the response recieved from the client in that variable.
ASKER
Sending the result on the appropriate socket in each thread, how is this achieved if the threads have been closed??
> how is this achieved if the threads have been closed??
the thread ending is not a problem. the socket being closed is though.
If you still need to communicate with the client then your run() method shouldn't close the connection.
Then add new method to your client thread class that sends the results to the client using the still open connection.
the thread ending is not a problem. the socket being closed is though.
If you still need to communicate with the client then your run() method shouldn't close the connection.
Then add new method to your client thread class that sends the results to the client using the still open connection.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Ive went in a different direction, its working at least, to stop one of the threads from executing i used a while loop waiting for the other thread to initialise a variable, when the variable got initialised the other thread had completed so the first could now complete.
I did try using a map but it seemed to go back to the same problem that I was trying to initially solve.
Using global variables is really what has gotten me out of this problem.
The help was good.
Thanks
I did try using a map but it seemed to go back to the same problem that I was trying to initially solve.
Using global variables is really what has gotten me out of this problem.
The help was good.
Thanks
8-)