Win a copy of Murach's Python Programming this week in the Jython/Python forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Synchronization not working -Thread  RSS feed

 
Abhi Venu
Ranch Hand
Posts: 73
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have created a class that implements runnanble interface

Here i have a
1. public void run method();
2.a synchronized method getChatFriends();





From another class

I created a new Thread .
I also called this getChatFriends(); But the execution was not sequential as expected .

I understands that sychronization works correct when the same object calls two different synchronized methods of a class..

I know somthing is wrong with this code.Please explain so that i could correct it








Class for creating Threads



Class for starting Thread



As i was using the same instance of Runnable ie "findusers" i exepected it to be sequential.But it is not working correctly




[HENRY: Added code tags. Formatted code]
 
Steve Luke
Bartender
Posts: 4181
22
IntelliJ IDE Java Python
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Abhi,

Can you provide more information on how 'it doesn't work'? What IS happening?

The code you provide doesn't help us at all, because it only calls the getChatFriends() method once, from the main method. I never see it called in another Thread. As a result I don't see how getChatFriends() would ever get called concurrently (unless you are running multiple applications). But there is a lot of missing code, so maybe the problem lies there.

So to begin with can you tell us how you launch your application and what problem you actually see?
 
Abhi Venu
Ranch Hand
Posts: 73
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hai steve,

Thanks for finding time to reply. I will post the code soon .actualy its a J2ME Midlet.

As you said getChatFriends() function is called only once.But i need to call this only after completion of execution

of thread searchUser which calls FindDevices(); function from the run method.

1.what i do is detect a set of blue tooth devices in its visibility range
2.populate a hash table once this process completes
 
Henry Wong
author
Sheriff
Posts: 22846
119
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
As i was using the same instance of Runnable ie "findusers" i exepected it to be sequential.But it is not working correctl


and

As you said getChatFriends() function is called only once.But i need to call this only after completion of execution

of thread searchUser which calls FindDevices(); function from the run method.


In the first case, you are implying that the two threads are running in parallel... while in the second case, you are expecting an order of who runs first.

Synchronization will make sure only one thread can own the lock -- and hence, only one can run at a time. Just because two threads tries to get the same synchronize lock doesn't mean that there is an order though. It's who gets the lock first that runs first.

Henry
 
Steve Luke
Bartender
Posts: 4181
22
IntelliJ IDE Java Python
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Abhi Venu wrote:Hai steve,

Thanks for finding time to reply. I will post the code soon .actualy its a J2ME Midlet.

As you said getChatFriends() function is called only once.But i need to call this only after completion of execution

of thread searchUser which calls FindDevices(); function from the run method.

1.what i do is detect a set of blue tooth devices in its visibility range
2.populate a hash table once this process completes


You need to call the getChatFriends method after the completion of searchUser (which calls FindDevices). You are calling the searchUser method multiple times in a Timer. So do you want to call the getChatFriends method after EACH call to FindDevices completes, after ALL calls to FindDevices complete, or after the FIRST call to FindDevices completes?

As for your synchronization:
You have the run() method of the TimerTask synchronized on the instance of TimerTask. This means the TimerTask's run method can only be executed one at a time (if called from multiple Threads, each run() method will wait for the previous one to finish before running). But the TimerTasks are all run in a single Timer thread, so there is no need to make TimerTask's run() method synchronized - because they all run in the same background thread they will all run sequentially.

You have the startSearch() method synchronized on the instance of MainForm. This startSearch() method, as far as shown, only is called from the TimeTask, which will be forced to run sequentially as described above, so it does not need to be synchronized either. But it also looks like you are trying to start the same Thread (searchUser) multiple times. This isn't possible, you will get IllegalThreadStateExceptions, as a Thread can only be started once. Of course, as the code you showed is written, it will not compile because startSearch() is not static, yet you try to call it from a static context (the TimerTask in a static main method), and beyond that you never assign a value to the MainForm's searchUser variable (you assign to a method-local variable in the main method), which would mean searchUser.start() comes up with a NullPointerException. So I suspect the code you posted isn't the real code, but some representation of the code you aren't really running - which also makes it hard to see for sure what is really happening.

You have the run() method and getChatFriends() of DeviceFinder synchronized on the instance of the DeviceFinder. This should effectively prevent FindDevices() from being called at the same time as getChatFriends(), as long as FindDevices() doesn't also generate a new Thread. Like Henry said, it doesn't guarantee what order your methods are called in so getChatFriends may execute before DeviceFinder#run(). If you want order you need to build your own. One way is a 'publishing' method where you trigger the getChatFriends() method to run at the end of the DeviceFinder#run() method then put the results in a place it can be accessed as needed:

Or it can be more difficult if you are using getChatFriends as a typical accessor, which means your have to force order using synchronization and wait()/notify():


This is just one way as an example, not exactly sure what fits your needs best but hopefully gets you started in the right direction.
 
Abhi Venu
Ranch Hand
Posts: 73
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hai steve,
No words to express my sincere thanks once again.


You are correct what i need is the list of all available devices....the list needs to be populated onl;y after the entire search is done....

ie if there are 5 devices i searches for devices first, after that i search for a particular service in these devices..if they run these services they can be called a as valid devices
which i can use....

As recommended by you rather than calling using thread i made direct calls to the methods using same object...expecting sequential execution since both methods i call are
synchronized and exists in same class
to use it in timer i made a function and made these calls from there





public class GuiForms extends MIDlet implements CommandListener,Runnable{


DeviceFinder findusers;


public void startApp() {
try {

/*1.INITIALISING DEVICE PROPERTES
2.STARTING THE INCOMING MESSAGE MONITOR THREAD
3.STARTING SEREVICE SAERCH THREAD
*/

findusers = new DeviceFinder();
timer = new Timer();
timer.schedule(new TimerTask(){
public void run(){
startDevicesearch(); // this method is e used to call two synchronized methods...
}
},1000,90000);






public void startDevicesearch()
{
findusers.FindDevices();
findusers.getChatFriends();
}


public synchronized void FindDevices()
{
boolean enquiryOver = DAgent.startInquiry(DiscoveryAgent.GIAC, this);
} catch (BluetoothStateException ex) {
ex.printStackTrace();
}
}




Actaully it works like this this statment "DAgent.startInquiry(DiscoveryAgent.GIAC, this); " fires a device search .....
after whole search is done call back method public void inquiryCompleted(int param) gets executed implicitly ,ie idont have any controll on it
.... The problem is that the startEnquiry method can return even before it gets into inquiryCompleted(int param) method...so if i call it in a timer
it will happen that 2 concuurent searching will occcur ending with some execeptions... so i am confused...


I am hesitant to post entire code because i feel it will be the most ugly code you may have ever seen...which will land you also in a pit of confusions..
so i think i will rather post relevant parts...so that you will have to spent only minimal time to get into the core problem of mine...
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!