Title: Java Multi Threading, make a thread wait for another thread, or joining different thread
Tags: java;multithreading;thread-safety
Question: this is my first time asking here. I have many times helped before when searching and always found this site. But now I can't found the answer for my problem. It has some kind of situation with many other question, but I can't found the one that's in my need.
Okay, so I have class named player, farm, and land. Farm is the kind of controller. Farm have an array of object called map, which is shared with land and player (given when they are constructed), and inside the map is player and land itself.
What I want to do is,
I left-click on farm, and I got the object from map based on where I clicked, then I save that object as selected. Then I right click other object and got the object, lets call it actioned. Actioned have a method, getMenu(selected),  which return a JPopMenu, based on selected. As an Example, if player is the selected, and land is actioned, the getMenu() will return menu "plow", "water" and "move". If I click at "plow", then the land will changed, and of course the map also changed, which shared with other object.
The problem is, I need the player to walk to grid near the land first, before the real action of plow begin. So in the plow menu I add an ActionListener like this:
new ActionListener() {
public void actionPerformed(ActionEvent e) {
int gx = (int)Point2D.this.X();
int gy = (int)Point2D.this.Y();
Object lock = new Object();
player.move(gx,gy,lock);
try {
lock.wait();
} catch (InterruptedException ex){}
// do the real action of plow here
}
}
And the move method of player
public void move(int gx,int gy,Object lock){
setDestination(gx, gy);
this.lock = lock;
The farm is a Runnable object, so every time the farm will call player.Update().
public void update(){
updatePosition();
if (position==destination) {
lock.notify();
I thought of made an object called lock there, and that object given to player. the Listener  is a running thread itself, and started when the menu is clicked, so I make the thread of Listener to wait, based on the lock object. The notify is given from the farm thread.
But of course, that is not working well, and throw java.lang.IllegalMonitorStateException. I don't really get what the synchronization explanation from the web. Question 1: How should I use the synchronization here to make the code work? Or what should I do if the synchronization will never work here?
I have also thought of using other approach.
I make the player as a runnable thread to. Now I have 3 thread, the farm, listener(land), and player.
So instead of make a lock object, I make a new Thread(Player). The run method of player:
while (position != destination) {
try {
Thread.sleep(100);
} catch (InterruptedException e){}
The new listener method:
Player player = (Player) selected;
int gx = (int)Point2D.this.X();
int gy = (int)Point2D.this.Y();
player.move(gx,gy);
Thread waitplayernotmoving = new Thread(player);
waitplayernotmoving.start();
try {
waitplayernotmoving.join();
} catch (InterruptedException e){}
It is work well enough. Question 2: is the land thread stop working while waiting the player thread? if not, how to make the land thread to stop while waiting the player thread dead?
And I have other problem. If I plow land1, and then while the player moving, I click at land2 and plow land2, the player is turning to land2! And then after it is not moving again, both of the land is plowed! Meaning the thread of land1 is still active.
I have two question:
Question 3: Is it possible to make the land1 thread die if I set another action to player, such as plow land2?
Question 4: Is it possible to make the land2 thread executed after land1 thread based on what my program doing now? So the action is like a queue. I plow land1, then plow land2, the action happen will be player move to land 1 and then plow land 1, then move to land2, and plow land 2.
Question 5 Remember my map, the array of object which is shared to all? How to ensure it is safe? I mean, looks like there will be many thread reading and writing the map. I read somewhere if it is immutable it won't be a problem. But it is re-written so often.. won't it be a problem?
Thank you very much for reading this long explanation, And I hope you can give me an answer. :(
Comment: Whenever you `wait` and `notify` on an object (in this case, `lock`), you need to execute these actions in a `synchronized` block.

Comment: Try making `move` a `synchronized` method. Here's a [link](http://www.coderanch.com/t/233943/threads/java/Synchronization-non-final-field) that may help clarify the warning. :)

Comment: @noob: Thanks, it's worked! And it's rise another problem, if I give another action the thread is deadlock -.- But I think I can handle it. Oh yeah, it's have a warning: "Synchronization on non-final field". Can you explain me what's its meant?

Comment: Okay, it will be my homework :)

Comment: @noob: That could actually make a pretty decent answer (at least to "Question 1").

Here is the accepted answer: I'll just answer one of these Question 5:
You say "if it's immutable it won't be a problem"  then you say "but it's re-written so often" - which I am going to take means it's not immutable.  The easiest way is to synchronize on the entire array.
synchronized (map) {
// modify map
The downfall of this is that you're now locking all your other threads anytime one wants to modify the array (even if only 1 is writing and 10 are reading).  And there' a big possibility that multiple concurrent threads don't actually want to modify the same element which should be fine.  The only case you need to worry about is when multiple threads want to change the same map element.  A second, more granular solution would be a read/write lock.  Only lock the entire map when I thread wants to change it, and never block on reads.  (see ReentrantReadWriteLock )
readLock.lock();
// read from map
} finally {
readLock.unlock();
writeLock.lock();
// modify map
} finally {
writeLock.unlock();
Now there is an even finer granularity where you only lock on individual elements in the map - but that's a little beyond the scope I think.  PLus gives you something to think about on your own.  Hope that helps.
Comment for this answer: Glad to help - did you get the whole problem figured out?
Comment for this answer: Thanks! It's a nice answer :) I will try it tonight. If I have a problem I'll be back. :D
Comment for this answer: I would like too, but I don't have enough reputation :( sorry :( when I have enough I promise will upvote it :)
Comment for this answer: I have enough reputation now :) Thanks @Gandalf :)
Comment for this answer: Yups. I got it :) I have a kind of mini diner dash game now. :)

Here is another answer: Okay, somehow I kind of found the answer, not for all though.
Question 1: Thx @noob comment, "Whenever you wait and notify on an object (in this case, lock), you need to execute these actions in a synchronized block". So I just make the lock in a synchronize block. Like this:
int gx = (int)Point2D.this.X();
int gy = (int)Point2D.this.Y();
Object lock = new Object();
player.move(gx,gy,lock);
synchronized(lock){
try {
lock.wait();
} catch (InterruptedException ex){}
}
Of course, when the lock giving notify also give it a synchronized block. But it's made a warning: "Synchronization on non-final field". It is because there is a chance the lock can be modified by other process, and will make a deadlock, because the lock is lose the reference.
Question 2: No. The land is still active. So it's using the resource. The thread still active while waiting the player thread died. You can use number 1 technique by making the thread wait. Thread that found wait() will give the monitor to other thread. it's kind of sleep, and wake up when object that invoke wait() invoke notify().
Question 3: Kind of found the answer, but still haven't trying it, so I won't answer.
Question 4: Yeah. It is possible. Make the player have a queue of lock instead of a lock. So in move(), instead of setting lock, it's adding lock to the queue. And the notify also do the same, it's only notify the front lock. After front lock, give a notify.
Question 5: Thx to @Gandalf answer, but still don't know whether I'm doing right or not. Don't know how to test it.

{'source': 'StackExchangeDataset', 'subset': 'stackoverflow.com', 'metadata': {'AnswerCount': 2, 'CommentCount': 5, 'ContentLicense': 'CC BY-SA 2.5', 'CreationDate': '2011:00:04/07/11', 'FavoriteCount': None, 'PostTypeId': 1, 'Tags': '<java><multithreading><thread-safety>', 'Title': 'Java Multi Threading, make a thread wait for another thread, or joining different thread', 'ViewCount': 2303, 'id': 5581548, 'user_AboutMe': '<p>adinata.us</p>\n', 'user_AccountId': 356882.0, 'user_DisplayName': 'dieend', 'user_Reputation': 2161.0, 'user_Views': 223.0, 'user_id': 696686.0}}