• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Cannot synchronise threads

 
Ranch Hand
Posts: 44
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I have tried to create a small program to demonstrate my understanding of synchronisation, and I just cannot get it to behave. My main class creates three threads with reference to the same object. I want the one thread to run, then one of the others, then the third. Problem is, I cannot get the threads to behave like this.

Here is my simple code:



Here is a snippet of the output:
In thread named sc1 value of stringbuffer: A. Count = 26
In thread named sc2 value of stringbuffer: A. Count = 2
In thread named sc3 value of stringbuffer: A. Count = 2
In thread named sc2 value of stringbuffer: A. Count = 3
In thread named sc3 value of stringbuffer: A. Count = 3
In thread named sc2 value of stringbuffer: A. Count = 4
In thread named sc3 value of stringbuffer: A. Count = 4
In thread named sc1 value of stringbuffer: A. Count = 27

clearly the threads are intermingled.

Can somebody help me with this? I ahve been messing with this for over an hour, and I am now forced to listen to my old Dead Kennedy collection as therapy...
 
author
Posts: 23956
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The problem is that synchronization of the doLoop() method uses the this object, which for the three threads are different. You need to synchronize on a common object.

Luckily, you have one... the string buffer. Change your code as follows.



Henry
 
Tony Bateman
Ranch Hand
Posts: 44
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Perfect! Works a treat; better still, I understand how a synchronisation block works. Thank you!

Now I don't understand how declaring a method to be synchronized would work. I thought that declaring the method as synchronized would stop other threads from accessing the method.

- Tony.
 
Henry Wong
author
Posts: 23956
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Tony Bateman:
Perfect! Works a treat; better still, I understand how a synchronisation block works. Thank you!

Now I don't understand how declaring a method to be synchronized would work. I thought that declaring the method as synchronized would stop other threads from accessing the method.

- Tony.



Synchronizing a method would stop other threads from accessing the method, or any other synchronized method, on the object. The keyword is "object". In this case, you have three different objects.

In this example, it is confusing because you are using thread objects. It would be much easier to envision of data objects that multiple threads are trying to access at the same time. It would only block if it is the same data that the threads are trying to access at the same time.

Henry
 
Tony Bateman
Ranch Hand
Posts: 44
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,

In the code example I posted, the doLoop() method is actually marked synchronized, and yet that did not prevent the method from being accessed by all three threads at the same time.
From my understanding so far, a method is shared by all instances of a class, so how come I get the problem even declaring doLoop() as synchronised?

Thanks for the previous answers: much appreciated.

- Tony.
 
Henry Wong
author
Posts: 23956
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Tony Bateman:
From my understanding so far, a method is shared by all instances of a class, so how come I get the problem even declaring doLoop() as synchronised?



For static methods, synchronization will prevent the execution, by other threads, of static synchronized methods, for all instances in the class.

For regular (instance) methods, synchronization will prevent the execution, by other threads, of regular synchronized methods, for an particular instance of a class.

In this example, it is a regular method, and you have three different instances.

Henry
[ September 20, 2005: Message edited by: Henry Wong ]
 
Tony Bateman
Ranch Hand
Posts: 44
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
OK thanks, getting there.

I'll go and buy a copy of your book if it's as clear as your explanations!

Thanks again,

Tony.
 
Greenhorn
Posts: 26
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I modified the program slightly and it work, but i am not in a position to explain.

class SynchronisedClass1 extends Thread
{
private StringBuffer scsb;

public SynchronisedClass1(StringBuffer sb)
{
scsb = sb;
}
public void run()
{
this.doLoop();
}
private synchronized void doLoop()
{

char c;
for (int i = 0; i < 100; i++)
{
System.out.println("In thread named "
+ Thread.currentThread().getName()
+ " value of stringbuffer: " + scsb
+ ". Count = " + i);
}
c = scsb.charAt(0);
c = (char)(c + 1);
scsb.replace(0,1,Character.toString(c));

}
}

public class TestSyncClass
{
public static void main(String[] args)
{
StringBuffer sb1 = new StringBuffer("A");
SynchronisedClass sc1 = new SynchronisedClass(sb1);
SynchronisedClass sc2 = new SynchronisedClass(sb1);
SynchronisedClass sc3 = new SynchronisedClass(sb1);
sc1.setName("sc1");
sc2.setName("sc2");
sc3.setName("sc3");
sc1.start();
sc2.start();
sc3.start();
}

}
 
reply
    Bookmark Topic Watch Topic
  • New Topic