I'm doing a Snake game in Java. I have the basic functionability, but I want pause the game when I click on a button. But the problem I have is when I clic on this button, the game is paused, but when I click again the game doesn't recognize the controls. I have a method called Init, on this I initialize the thread "Hilo". I tried to make a second thread in which I put an actionPerformed for the button, but the problem continued, now I am more confused. Here is my code:
Thread hilo; //I declared the thread
String state=""; //It is for control de state (paused or no)
Runnable hiloFor = new Runnable()
{
public void run()
{
Thread actual = Thread.currentThread();
synchronized(actual)
{
do
{
//Game instructions (there are a lot of them)
if(state.equals("paused"))
{
actual.wait();
}
}while(!option.equals("Exit"));
}
}
};
//This is my action performed where I control if it is paused
public void actionPerformed(ActionEvent e)
{
if ( e.getSource() == btnPause )
{
if(state.equals("paused"))
{
cont(); //method for reactive the thread
state="";
}else if(state.equals(""))
{
state="paused";
}
}
}
If somebody can help me, I will be very glad, It has turned difficult to me.
To reactivate the Thread in wait() you must call notify() (or better notifyAll()) on the same object.
Your code looks like you expect to pause the Thread you call wait() on. This is not the case. wait() will always pause the thread making the call, not the object that is the target. You can use any object for the wait() / notifyAll() signaling, it just has to be the same object for both sides of the communication.
This pages has some good explanations: http://javamex.com/tutorials/synchronization_wait_notify.shtml
if(state.equals("paused"))
{
actual.wait();
}
This part actually pauses the thread, until it's told to start it's work again. I suppose what you wanted in this case is something like continue; in loop, which, although, is not a very elegant way to do this. More suitable way to do this would be using notify().
Related
I have a jframe i want to display while my main frame is running. i want to pause my main code, until the user does the necessary actions on the other frame. I've read a lot of solutions but i need to see it done for my code to understand and grasp it fully. i do not want to use jdialog like I've seen listed as an answer before. My main goal is to understand better threading so that i can use what i learn in different cases.
With the code I've created, when running the thread, only just the frame loads, none of the other features are there on the frame. (the frame is simple it has a label, a list the user selects from, and a button to basically return the chosen list value.) its like the thread is cut off from completing or something.
here is my class calling the screen:
public class myThread implements Runnable {
String result = null;
public void run() {
MessageScreen ms = new MessageScreen();
ms.setVisible(true);
}
public String getResult() {
return result;
}
public void setResult(String AS) {
result = AS;
}
}
in my main code, a method is called that is returning a String[] value, with this method at some point i have the following code calling the new thread to get the value necessary to return in the original main method:
myThread mt = new myThread();
Thread t = new Thread(mt);
t.start();
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
myreturn = new String[] {"true", mt.getResult()};
without listing the whole code for the second frame, when the user presses the button, and at the end of the listener tied to the button press the i want to close the frame and return a string that was selected from the list:
jf.dispose();
myt.setResult(AdminSelection);
in the frame class, i have the following instance variables declared:
String AdminSelection = null;
myThread myt;
i hope this is enough information for someone to help me out and understand whats gone wrong here.
The function join() waits until the end of the run() method, when you do t.join(), your thread is already or almost ended. This is because in your run() method there is nothing that blocks the thread until the user has clicked the confirm button. And is better like this!
There is no sense to create a thread here, you should use a callback, or more generally in Java, a listener. You can take a look at Creating Custom Listeners.
But, especially if you want to pause your main code, you should use a (modal) JDialog which is made for this! Don't try to block the UI by yourself, you could block the UI thread (handled by Swing/AWT) by mistake. Creating a JDialog is better because everything is already made for this usage on the UI thread.
Also, you must know that create a Thread is really long, use a Thread when you really need it.
When I click the stop button on my GUI which invokes the code below through an event listener, the GUI stops responding. I know wait() has to be synchronized, but what is the correct way to invoke it? Thanks in advance!
public void actionPerformed(ActionEvent actionEvent) {
if(actionEvent.getSource().equals(ui.stop)) {
if(clickerThread != null) {
/*terminate() stops the while loop
running in the thread's run(); */
autoClicker.terminate();
synchronized(clickerThread) {
try {
clickerThread.wait();
ui.updateLabel("Idle", ui.state);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
This is how the thread was created in case it helps:
else if(actionEvent.getSource().equals(ui.play)) {
if(clickerThread == null) {
autoClicker= new AutoClicker();
clickerThread = new Thread(autoClicker);
clickerThread.start();
ui.updateLabel("playing", ui.state);
}
}
As you're finding out, calling wait() does not freeze the thread that it's called on (in fact it can be called on any "monitor" object -- thread or not), but rather the thread that its called in. Per the Object API (and do make it a habit to read the API before asking):
Causes the current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object.
Much better to give your clickerThread class a public method that the GUI can call that pauses and resumes execution. So perhaps you wish to give your clickerThread class a volitile boolean field that it checks when deciding whether to continue running or not, and then give the class a public method to set this field's value.
I got an assignment for university where I have to implement a hangman game with Threads in Java.
My problem is that I can't understand how to handle the threads.
In my code there is a GameLeader who prompts the GuessingPlayer to enter a char which he guesses in the startWord. After he did that (run()-method) he takes the message further.
The connection between the two players should be arranged with 'Messages' (own implemented class). It's working if I use run() instead of wait().
Can u help me to understand why the while loop is not working after the first entered message?
Thanks!
Class GameLeader:
public class GameLeader {
public static void main(String[] args) throws IOException {
GuessingPlayer guessingPlayer = new GuessingPlayer(userInterface);
String guess;
System.out.println("Please enter a startWord to begin!");
String startWord = userInterface.enterWord();
guessingPlayer.start();
while (attempts < 11) {
synchronized (guessingPlayer) {
System.out.println("It's your turn, Guessing Player!");
guessingPlayer.wait();
guess = guessingPlayer.message.toString();
if (startWord.contains(guess)) {
...
}
} else {
...
}
userInterface.mainMenu(guess);
}
}
}
}
Class GuessingPlayer:
public class GuessingPlayer extends Thread {
Message guessMessage;
private UserInterface userInterface;
GuessingPlayer(UserInterface userInterface) {
this.userInterface = userInterface;
}
#Override
public void run() {
synchronized (this) {
guessMessage = new Message(userInterface.enterWord());
notify();
}
}
}
I think you would be well served to review the course material on threads, and/or talk to your instructor. But, a few comments and suggestions:
I imagine the game leader is supposed to be a thread, and the player(s) are also supposed to be threads (as your current GuessingPlayer class is). These are all instantiated and started when your program starts by calling the start() method on the thread.
You don't have to call run, that gets called internally by the thread once it's started. But you probably want a loop in the run method that waits for the thread to be notified, and then repeats.
By "message passing" they mean something general like having a shared object or Queue that all the threads can read/write and have a reference to. One thread writes something in that object, and calls Thread.notify() to notify the other threads that something interesting has happened in that object. When that happens, the other thread will wake up right where it called the Thread.wait() method. Then it can check that shared object to see what's up.
http://web.mit.edu/6.005/www/fa14/classes/20-queues-locks/message-passing/
http://www.programcreek.com/2009/02/notify-and-wait-example/
Hope this helps.
You are using wait() method in a wrong way. You do not need an object reference to call wait() method. It is a method defined in Java's Object class.
Therefore, just write wait() instead of using guessingPlayer object reference.
Hope this helps. :)
I didn't fully understand the concept of threads I have some questions. Assume we have the following code:
ExecCommand.java
// I don't know how this work, for now
package therads;
// Here we will have the methods and run them from the Main.java
public class ExecCommand implements Runnable
{
String name;
int time;
public ExecCommand(String s,int amount)
{
name = s;
time = amount;
}
// Run method (Runnable)
public void run()
{
try
{
// What to execute when the thread is started
System.out.printf("%s is sleeping for %d\n",name,time);
Thread.sleep(time);
System.out.printf("%s is done\n",name);
}
catch(Exception e)
{
}
}
// This dosen't work when the thread is stopped
public void stop()
{
try
{
System.out.printf("STOPPED!");
}
catch(Exception e)
{
}
}
// This dosen't work when the thread is started
public void start()
{
try
{
System.out.printf("Started!");
}
catch(Exception e)
{
}
}
}
and i call him from :
Main.java
Thread t5 = new Thread(new ExecCommand("Good Function",1000));
t5.start();
I want to println() "Started" when the thread is started and "Stopped" when it finished. It is possible?
When a thread is completed, it dies, complete released from memory? If not, how i can do that?
How can i make a thread that repeat itself like once every 1000 miliseconds till i press a key? I was thinking about while(true) { t5.start; }
but i don't know for sure.
First of all, there is no point in using the start and stop methods. Everything happens in the run method.
To print a message on start and stop, put them at the start and end of the run method. To loop indefinitely and keep executing code until an outside event happens, use a flag and loop on it:
class ThreadTask implements Runnable {
private volatile boolean flag = false;
public void setFlag(boolean value) {
flag = value;
}
public void run() {
System.out.println("Started");
while(!flag) {
// execute code
}
System.out.println("Stopped");
}
}
Then when you want the thread to stop, just set the flag to true using setFlag.
And yes, threads are automatically cleaned up by the runtime + OS after the run method terminates.
Why or when would you expect your .start() and .stop() to be called? Runnable has only a single method in the interface; .run(). The JavaDocs for Thread cover it pretty well. http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html. If you want something to happen when your Thread starts, put that something at the top of your .run(). If you want something to happen when your Thread is finishing, put it at the bottom of the .run(). By-in-large doing anything with the .start() and .stop() methods on Thread is discouraged. Concentrate on doing all you lifecycle stuff within your .run(). And get a copy of "Java Concurrency in Practice" by Goetz. It will show you the full range of your options (including don't do you own Threading directly).
You are not supposed to override the start and stop methods. They are not callback methods.
What you want is something akin to the SwingWorker class (assuming you are interested in UI related threading synchronization).
If not, you can subclass Thread yourself and provide a callback mechanism.
Yes of course. You can just print "Started" in the first line of your run() method, and print "Stopped" either in a finally section of run() method or just after t5.join()
You are not told about the details, and cannot do anything. But you can assume the resources are freed as soon as necessary. (Of course if you have reachable links for any references allocated within your thread, JVM cannot decide that these are of no use, so "complete" is not a proper word here.)
Take a look at java.util.Timer
If you prefer to use System.out.println instead of printf just change those lines of code. There's nothing thread-related about those calls.
The thread will be collected and released from memory by the garbage collector when it has stopped running and there are no live references to it. Same as all objects.
Don't override stop(). This has been deprecated and should really be dealt with by the JVM, not your application code. Just override run to implement whatever you want your thread to do, as per the docs
You can use Thread.sleep to sleep for a period of time. How accurate the sleep will be will depend on your platform and the resolution of the available system clock.
I have made a java program with GUI and I want a stop button functionality in which when a user clicks on the stop button, the program must be stopped.
In my program, the main thread starts other 10 threads and I want that whenever the stop button has been clicked all the 10 threads must be stopped before the main thread.
Second, I also want that whenever any thread of those 10 threads is stopped, it must first close all the resources it had opened before like connection to a database etc.
I have implemented the code as answered by ........
Now there is one problem.
My thread class is like this:
public class ParserThread implements Runnable {
private volatile boolean stopped = false;
public void stopTheThread() {
stopped = true;
}
:
:
}
And below is the main thread that starts 10 threads from the function start()
public class Main() {
Thread [] threads;
public void start() {
for(int i = 0; i < 10; i++) {
threads[i] = new Thread(new ParserThread());
}
}
public void stop() {
// code to stop all the threads
}
}
Now I want to call the stop method of the ParserThread to set "stopped = true" to stop the thread. I want this thing to be done for all the 10 threads.
How can I call that stop method. I want it to be done in the stopAllThreads() method of the Main class.
Generally speaking, the way to do this is to have each of the other threads periodically check a flag. Often background threads loop, waiting for work - they just have to check the flag each time they go round a loop. If they're using Object.wait() or something similar to be told that there's more work, the same notification should be used to indicate that the thread should stop too. (Don't just spin until you're stopped - that will suck CPU. Don't just use sleep - that will delay termination.)
That allows all threads to terminate cleanly, releasing resources appropriately. Other options such as interrupt() and the deprecated destroy() method are much harder to control properly, IMO. (Interrupting a thread is better than hard-aborting it, but it has its own set of problems - such as the interruption is only processed at certain points anyway.)
EDIT: In code, it would look something like:
// Client code
for (Task task : tasks) {
task.stop();
}
// Threading code
public abstract class Task implements Runnable {
private volatile boolean stopped = false;
public void stop() {
stopped = true;
}
protected boolean shouldStop() {
return stopped;
}
public abstract void run();
}
Your tasks would then subclass Task. You would need to make it slightly more complicated if you wanted the stop() method to also notify a monitor, but that's the basic idea.
Sample task:
public class SomeTask extends Task {
public void run() {
while (!shouldStop()) {
// Do work
}
}
}
I don't think the answer solve the issue. here the code:
public class SomeTask extends Task {
public void run() {
while (!shouldStop()) {
// Do work
}
}
}
But how to handle if the "Do work" hang and does not return? In this case, the while cannot check the flag. The Thread still cannot stop.
The possible solution to this might be using Process.
Have a controller object which has a flag whether the threads should stop or not and each thread checks the controller periodically and exits if stop button is clicked (for example if you are transferring a file, then after each block is received/sent, check if stop is clicked).