I have class Client and method called listRooms().
public synchronized RoomInfo[] listRooms() {
sendMessage(new Message("#refresh"));
try {
System.out.println("#1");
wait();
System.out.println("#2");
} catch (InterruptedException e) {
e.printStackTrace();
return null;
}
if( m_RoomListMessage == null )
return null;
RoomInfo[] rooms = new RoomInfo[ m_RoomListMessage.getInteger(0) ];
for(int i=0; i<rooms.length; i++) {
rooms[i] = new RoomInfo(
m_RoomListMessage.getString(3*i + 1),
m_RoomListMessage.getBoolean(3*i + 2),
m_RoomListMessage.getInteger(3*i+3)
);
}
return rooms;
}
I also have class Listener (extends Thread) which listens for incoming messages from server. As the message arrives listener thread reads Message (using ObjectInputStream) and then calls next method.
public synchronized void processMessage(Message aMessage) {
if( aMessage.type.equals("#roomlist") ) {
m_RoomListMessage = aMessage;
notify();
System.out.println("notificiran xD");
return;
}
MessageHandler handler = m_MessageHandlers.get(aMessage.type);
if( handler == null ) {
System.out.println("No MessageHandler for: " + aMessage.type);
return;
}
handler.onMessage(aMessage);
}
The problem is it waits forever. processMessage() is never called after I sent #refresh message and my server shows that it sent message containing list of all rooms on server, also method is called from Listener thread but listRooms() is called from object LobbyView (extends View which extends JPanel) attached to object of ClientWindow (extends JFrame), so it is different thread. And I don't know why is it blocked. So Listener obviously cannot call processMessage but I don't know why or I have some wrong understanding of threads in Java :D
EDIT: It also indicates that Listener thread is blocked for some reason...
The problem is it waits forever. processMessage() is never called after I sent #refresh message
Looks to me that your listRooms() call is doing a wait on the Client object while your processMessage(...) method is calling notify() on a Listener object. For the notify() to wake up the other thread it must be on the same object instance. When you have a synchronized method, it is locking on the this object instance.
These two objects must share a common lock object to be able to signal each other. One way you can do this is to pass in a lock object into both the Client and the Listener and then do something like:
synchronized (commonLock) {
commonLock.wait();
}
...
synchronized (commonLock) {
commonLock.notify();
}
EDIT: It also indicates that Listener thread is blocked for some reason...
I don't know why the Listener would be blocked but it's not because of the notify() call.
Related
I am trying to implement standard Producer Consumer problem using java.
I done some code to do it.
Here is the code:
Producer Class:
class Producer implements Runnable
{
public Producer()
{
new Thread(this,"Producer").start();
}
public synchronized void put()
{
while(Q.valueset)
{
try
{
wait();
}
catch(Exception e)
{
System.out.println(e);
}
}
Q.valueset=true;
Q.i++;
System.out.println("Put:"+Q.i);
notify();
}
public void run()
{
while(true)
{
put();
}
}
}
Consumer class:
class Consumer implements Runnable
{
public Consumer()
{
new Thread(this,"Consumer").start();
}
public synchronized void get()
{
while(!Q.valueset)
{
try
{
wait();
}
catch(Exception e)
{
System.out.println(e);
}
}
Q.valueset=false;
notify();
System.out.println("Get:"+Q.i);
}
public void run()
{
while(true)
{
get();
}
}
}
Another class for Static variables:
class Q
{
static boolean valueset=false;
static int i;
}
I am having one more class which only contains main and creates the instance of Producer And Consumer.
Now when i am trying to run this program it gives following output:
Put:1
put:2
Got:1
Got:2
I am having misconception related to Wait() and notify() that how it works and how object enters and out's from the monitor.i wanted to clear that concept.
Here the problem is also arising due to Wait and notify().
I know this is very basic question related to Multithreading but these these will help me to clear my misconception.
And i also wanted to understand what is the problem in my code.
I already gone through the following link:
producer - consumer multithreading in Java
You need to wait() and notify() on some shared object. What you are doing now by using synchronized is waiting on the respective objects themselves, i.e. the Producer is waiting on the Producer and the Consumer on the Consumer object. You need to wait on something in Q.
From the Javadoc:
notify(): Wakes up a single thread that is waiting on this object's monitor.
wait(): The current thread must own this object's monitor. The thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object's monitor to wake up either through a call to the notify method or the notifyAll method. The thread then waits until it can re-obtain ownership of the monitor and resumes execution.
This object's monitor in your case is this, which is your Producer in the put() case and the Consumer in the get() case. But in order for the notify to notify the other Thread, they need to have the same monitor, i.e. they need to wait() on the same object. This object can be e.g. a Object variable in your Q.
To get you started, this is what I mean:
class Q
{
static boolean valueset=false;
static int i;
static Object myLock = new Object();
}
public void put() {
synchronized (Q.myLock) {
while (Q.valueset) {
try {
Q.myLock.wait();
} catch (Exception e) {
System.out.println(e);
}
}
Q.i++; //you forgot this as well
System.out.println("Put:" + Q.i);
Q.valueset = true;
Q.myLock.notify();
}
}
You can fill in the Consumer class yourself...
Put:1
Get:1
Put:2
Get:2
Put:3
Get:3
Put:4
Get:4
This post explains the relationship between notify, wait, and other things you are looking for.
Difference between wait() and sleep()
I have a class which is a listener for incoming messages and should be alive forever (So that it can listen for incoming messages) until i explicitly disconnect the connection for it. I have declared the thread as setDaemon(false) but it terminates with the calling methods termination.
Please tell me how to keep that thread alive and also please throw some light on how to implement the Spring TaskExecutor to achieve same.
Thanks in advance.
it is a listener it gets notified when someone sends message... so how do i keep it running ?
The Listener Class
public class MyListnerImpl implements Listener {
private final connectionImpl con;
public MyListnerImpl(ConnectionImpl con) {
if (con.isAuthenticated() && con.isConnected()) {
if (logger.isInfoEnabled()) {
logger.info("Initializing XmppListner:");
}
this.itsCon = con;
Thread t1 = new Thread(this);
t1.setDaemon(false);
t1.start();
}
}
public final void listnerInterfaceMethod(final Chat chat, final Message message) {
System.out.println("Message" + message);
}
public final void run() {
itsCon.getChatManager().addChatListener(new ChatManagerListener() {
public void chatCreated(final Chat chat, final boolean createdLocally) {
if (!createdLocally) {
chat.addMessageListener(itsFbml);
}
}
});
}
}
Calling class simply creates its object and thread gets started by the Listeners constructor.
I want to keep this thread created run until i interrupt it.
There are a few things you could do that would be better than hanging the initial thread forever:
Use otherThread.join(). This will cause the current thread you are running in to sleep until the other thread has finished executing.
As #nanda suggests, use ExcecutorService.shutdown() to wait until a pool of threads has finished.
Use otherThread.setDaemon(false) and simply let your initial thread exit. This will set your new threads as user threads. Java will not shut down until the only threads running are daemon threads.
synchronized(this) {
while (true) {
this.wait();
}
}
This will make the current thread wait on the monitor of the current class until someone calls notify(), or forever.
copied from How do you hang a thread in Java in one line?
A thread says alive until run() returns (or throw an error/exception) If you want to keep it alive, use a loop, don't return and catch any error/exception.
This is how i solved the problems that time,
So this case was not of multi threading , had just a single thread which needed to run for ever,
So Inserted
public final void run() {
while(true)
{
//Run Method Logic...
}
}
And instantiated it from a spring bean.
I was also looking at more fancy things for this single threaded scenario like awaitTermination(); or something like that.
I have got a main thread and within that thread I start a new thread. (the child thread). That child thread opens a server socket and starts listening for a connection.
I want that thread to stop its execution and close whatever it has initialized (like the Socket) when the main thread gets a message from outside (from where it gets the the message is not the concern). How should I stop the thread and close all the connections is what I want.
Should I use a shared variable? so that when the main thread receives the message it should modify it and the child thread should continually check for the changes in that shared variable?
How should I implement it? Some useful links may help or a sample code ?
What I have tried is as follows:
in the main thread I have declared a variable
flag=0;
when the main thread receives the message, it sets
flag = 1 ;
and the thread listens for the change as follows:
void ()run{
while(true){
if(flag==1){
break;
}
sock1 = Ssocket.accept();
}
But the above code is not at all working. How should I do it?
The proper way to interrupt a thread is via the interruption mechanism. In your main thread, when you want to stop the child thread, you call:
childTread.interrupt();
and in the child thread, you do something like:
public void run() {
try {
while (!Thread.currentThread.isInterrupted) {
sock1 = Ssocket.accept();
//rest of the code here
}
} catch (InterruptedException e) {
Thread.currentThread.interrupt(); //good practice
}
//cleanup code here: close sockets etc.
}
Note that Ssocket.accept isn't interruptible, so if you want to stop it from waiting, you will have to close it from outside, to force it to throw an IOException.
Child thread
You should make a new function here, f.e:
public void setFlag(int i)
{
flag = i;
}
Parent Thread
Whenever you want to kill/stop listening/... in the child thread, make a call to:
childThread.setFlag(1);
If you don't need the child Thread to be anonymous, create a ChildThread class:
public ChildThread implements Runnable
{
private int flag = 0;
public ChildThread()
{ }
public void setFlag(int i)
{
flag = i;
}
public void run()
{
//your code
}
....
}
If you are using a flag to signal a thread to stop, make sure read/write access is synchronized. For example:
public synchronized void cancel ()
{
stop = true;
}
protected synchronized boolean cancelRequested ()
{
return stop;
}
Extend Runnable with your own implementation:
public class StoppableRunnable extends Runnable {
}
Code your class so that you can stop the execution of the Runnable, you will find a good example of how to do this here How to properly stop the Thread in Java?. Make sure you look at the first two answers.
In your equivalent of the terminate() function, do all your cleanup
The problem is simple. On Android I have a method that needs to call a library function. The call will signal a callback that I must handle. Before I return from my method, I must wait for that callback to be signaled.
I thought the wait() and notify() methods on a monitor object would do the trick. It does not.
Basically the monitoring object is called Connection which I instantiate in the calling method. The method then does a loop where it calls an Android library method to 'unregister' an object. Unfortunately the response to this method is given in some callback. So I use the Connection.wait(10000) method to wait for the callback, and in the callback I use connection.notify() to signal when it gets done (all synchronized, of course). However, the connection.notify() does not release the connection.wait(10000). I can see from the Android logcat that the unregistration succeeds BUT I always have to wait 10 seconds before the next unregisration task is attempted.
The code for the calling method and the callback are below. What stupid assumption am I making in my reasoning that this fails. As far as I can see the calling method (thread) definitely owns the monitoring Object and gives it up to the callback on the connection.wait(10000)!
Maybe I am using an entirely incorrect approach for this problem? (What I want is the method to block the caller until all the unregistrations are done.)
public void clearRegistrations()
{
connection = new Connection();
// Tell the callback to notify() when a result is obtained
connection.setUseNotify(true);
for(BluetoothHealthAppConfiguration btConfig : btHealthAppConfigs)
{
// Initialize Connection object to not connected
connection.setConnectionState(false);
if(btHealth.unregisterAppConfiguration(btConfig))
{
try
{
synchronized (connection)
{
connection.wait(10000);
// See if we were signaled or timed out
if(!connection.getConnectionState())
{
Log.i(TAG, "Unregistration attempt timed out or failed; trying next un-registration");
}
}
}
// This should not happen
catch(InterruptedException ie)
{
Log.i(TAG, "The InterrupedException is signaled.");
}
// This should not happen.
catch(IllegalMonitorStateException ime)
{
Log.i(TAG, "wait() method threw an IllegalMonitorStateException. Message: " + ime.getMessage());
}
}
else
{
Toast.makeText(context, "Un-Registration API returned failure", Toast.LENGTH_SHORT).show();
}
}
btHealthAppConfigs.clear();
connection.setConnectionState(false);
connection.setUseNotify(false);
}
The callback is as follows and it is in the same class as the method above but it is one of those 'onSomeEvent()' that is so popular in Android:
public void onHealthAppConfigurationStatusChange(BluetoothHealthAppConfiguration btAppConfig, int status)
{
if (status == BluetoothHealth.APP_CONFIG_UNREGISTRATION_FAILURE)
{
Log.i(TAG, "Un-Registration of the Bluetooth Health Application failed");
if(connection.useNotify() == true)
{
synchronized (connection)
{
Log.i(TAG, "Signal unregistration failure");
// just indicate signaled
connection.setConnectionState(true);
connection.notify();
}
}
}
else if(status == BluetoothHealth.APP_CONFIG_UNREGISTRATION_SUCCESS)
{
Log.i(TAG, "Un-Registration of the Bluetooth Health Application successful");
if(connection.useNotify() == true)
{
synchronized (connection)
{
Log.i(TAG, "Signal unregistration success");
connection.setConnectionState(true);
connection.notify();
}
}
}
}
There are a bunch of things that might be wrong with this code: assylias got most of them. The obvious thing is that you definitely need to use notifyAll, instead of notify. notify restarts some thread waiting on a lock; notifyAll restarts them all.
useNotify and setConnectionState also need to be synchronized. Also you need to guarantee that the instance of connection on which you are locking, is the same in both sections, and is the same one on which you call notify. Lastly, you need to guarantee that the call to notify actually happens after the call to wait.
As far as approach, anytime you use such low-level tools, you ought to wonder if there isn't a better way. There are several higher-level constructs that could do this more simply. I would suggest that you try to re-design you code so that you don't wait on the callback. Make the call, park the state somewhere, and then handle the callback when it happens.
I'm using a thread that is continuously reading from a queue.
Something like:
public void run() {
Object obj;
while(true) {
synchronized(objectsQueue) {
if(objectesQueue.isEmpty()) {
try {
objectesQueue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
obj = objectesQueue.poll();
}
}
// Do something with the Object obj
}
}
What is the best way to stop this thread?
I see two options:
1 - Since Thread.stop() is deprecated, I can implement a stopThisThread() method that uses a n atomic check-condition variable.
2 - Send a Death Event object or something like that to the queue. When the thread fetches a death event, it exits.
I prefer the 1st way, however, I don't know when to call the stopThisThread() method, as something might be on it's way to the queue and the stop signal can arrive first (not desirable).
Any suggestions?
The DeathEvent (or as it is often call, "poison pill") approach works well if you need to complete all of the work on the queue before shutting down. The problem is that this could take a long time.
If you want to stop as soon as possible, I suggest you do this
BlockingQueue<O> queue = ...
...
public void run() {
try {
// The following test is necessary to get fast interrupts. If
// it is replaced with 'true', the queue will be drained before
// the interrupt is noticed. (Thanks Tim)
while (!Thread.interrupted()) {
O obj = queue.take();
doSomething(obj);
}
} catch (InterruptedException ex) {
// We are done.
}
}
To stop the thread t that instantiated with that run method, simply call t.interrupt();.
If you compare the code above with other answers, you will notice how using a BlockingQueue and Thread.interrupt() simplifies the solution.
I would also claim that an extra stop flag is unnecessary, and in the big picture, potentially harmful. A well-behaved worker thread should respect an interrupt. An unexpected interrupt simply means that the worker is being run in a context that the original programmer did not anticipate. The best thing is if the worker to does what it is told to do ... i.e. it should stop ... whether or not this fits with the original programmer's conception.
Why not use a scheduler which you simply can stop when required? The standard scheduler supports repeated scheduling which also waits for the worker thread to finish before rescheduling a new run.
ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
service.scheduleWithFixedDelay(myThread, 1, 10, TimeUnit.SECONDS);
this sample would run your thread with a delay of 10 sec, that means when one run finishes, it restarts it 10 seconds later. And instead of having to reinvent the wheel you get
service.shutdown()
the while(true) is not necessary anymore.
ScheduledExecutorService Javadoc
In your reader thread have a boolean variable stop. When you wish for this thread to stop set thius to true and interrupt the thread. Within the reader thread when safe (when you don't have an unprocessed object) check the status of the stop variable and return out of the loop if set. as per below.
public class readerThread extends Thread{
private volitile boolean stop = false;
public void stopSoon(){
stop = true;
this.interrupt();
}
public void run() {
Object obj;
while(true) {
if(stop){
return;
}
synchronized(objectsQueue) {
if(objectesQueue.isEmpty()) {
try {
objectesQueue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
if(stop){
return;
}
obj = objectesQueue.poll();
// Do something with the Object obj
}
}
}
}
public class OtherClass{
ThreadReader reader;
private void start(){
reader = ...;
reader.start();
}
private void stop(){
reader.stopSoon();
reader.join(); // Wait for thread to stop if nessasery.
}
}
Approach 1 is the preferred one.
Simply set a volatile stop field to true and call interrupt() on the running thread. This will force any I/O methods that wait to return with an InterruptedException (and if your library is written correctly this will be handled gracefully).
I think your two cases actually exhibit the same potential behavior. For the second case consider Thread A adds the DeathEvent after which Thread B adds a FooEvent. When your job Thread receives the DeathEvent there is still a FooEvent behind it, which is the same scenario you are describing in Option 1, unless you try to clear the queue before returning, but then you are essentially keeping the thread alive, when what you are trying to do is stop it.
I agree with you that the first option is more desirable. A potential solution would depend on how your queue is populated. If it is a part of your work thread class you could have your stopThisThread() method set a flag that would return an appropriate value (or throw Exception) from the enqueuing call i.e.:
MyThread extends Thread{
boolean running = true;
public void run(){
while(running){
try{
//process queue...
}catch(InterruptedExcpetion e){
...
}
}
}
public void stopThisThread(){
running = false;
interrupt();
}
public boolean enqueue(Object o){
if(!running){
return false;
OR
throw new ThreadNotRunningException();
}
queue.add(o);
return true;
}
}
It would then be the responsibility of the object attempting to enqueue the Event to deal with it appropriately, but at the least it will know that the event is not in the queue, and will not be processed.
I usually put a flag in the class that has the Thread in it and in my Thread code I would do. (NOTE: Instead of while(true) I do while(flag))
Then create a method in the class to set the flag to false;
private volatile bool flag = true;
public void stopThread()
{
flag = false;
}
public void run() {
Object obj;
while(flag) {
synchronized(objectsQueue) {
if(objectesQueue.isEmpty()) {
try {
objectesQueue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
obj = objectesQueue.poll();
}
}
// Do something with the Object obj
}
}