i was working with the synchronized statement and made the following program...synchronized the runn class with this as object reference ..bt smhw the desired output is nt there....
class runn extends Thread {
String s;
runn(String a) {
s=a;
start();
}
public void show() {
System.out.print("["+s);
try {
sleep(50);
} catch(Exception a){}
System.out.print("]");
}
public void run() {
synchronized(this) {
show();
}
}
}
public class multi4 {
public static void main(String[] args) throws InterruptedException{
new runn("hello ");
new runn("this is ");
new runn("multithreading");
}
}
The output should be :
[hello][this is][multithreading]
but synchronisation is not working smhw
Please help.
Two mistakes:
You synchronized on the individual runn objects. This has no effect because each thread uses a different synchronization object.
The synchronized keyword does not magically cause threads to run in order. It merely prevents threads from attempting to execute the synchronized block at the same time, if you synchronize on the same object. They may still run in any order, but wouldn't be able to interleave their output. That is, if you synchronized on a shared object, you could get e.g. [this is][hello][multithreading], but not [this is[hello][multithreading]].
Related
I am currently learning the use of monitor in Java, but i do not know how the synchronized methods work.
I understand that while one thread is inside a synchronized method, another thread cannot be inside a synchronized method and that sleep doesn't take off the monitor's own ownership.
So i tried to write a code to test that
import java.util.Random;
public class ex3 extends Thread {
private static int nbA=0;
private static int nbB=0;
public static final Random rand = new Random();
public void run(){
while(true){
System.out.println(nbA+" "+nbB);
try{
Thread.sleep(rand.nextInt(500));
}catch (Exception e ){e.printStackTrace();}
if (rand.nextBoolean()){
try {
A();
} catch (InterruptedException e) {}
}else{
try {
B();
} catch (InterruptedException e) {}
}
}
}
public synchronized void A() throws InterruptedException{
nbA++;
Thread.sleep(rand.nextInt(500));
nbA--;
}
public synchronized void B() throws InterruptedException{
nbB++;
Thread.sleep(rand.nextInt(500));
nbB--;
}
public static void main(String[] argv){
new ex3().start();
new ex3().start();
new ex3().start();
}
}
I believed it was impossible that nbA or nbB be superior to 1 or that nbB and nbA are both >0 but it's happening
What do I misunderstand ?
Sorry for the bad english.
You're synchronizing on different objects: a synchronized non-static method synchronizes on this, so each of the new ex3() instances effectively works like it's not synchronized.
A synchronized instance method is exactly equivalent to this:
public void A() {
synchronized (this) {
// The body.
}
}
Either make the synchronized methods static, or explicitly synchronize on the class (or something other shared object):
public void A() throws InterruptedException{
synchronized (ex3.class) {
nbA++;
Thread.sleep(rand.nextInt(500));
nbA--;
}
}
I understand that while one thread is inside a synchronized method, another thread cannot be inside a synchronized method
Wrong. It cannot be inside a synchronized method synchronized on the same object. It can be inside any other synchronized method, or the same method synchronized on a different object, as here.
and that sleep doesn't take off the monitor's own ownership.
Correct.
NB Per Brinch Hansen doesn't consider Java to have monitors, and he invented them.
From the tutorial I read:
it is not possible for two invocations of synchronized methods on the
same object to interleave. When one thread is executing a synchronized
method for an object, all other threads that invoke synchronized
methods for the same object block (suspend execution) until the first
thread is done with the object.
However, in my simple example there is still a race competition to access the message object.
public class TestThread extends Thread{
int thread;
StringBuilder message;
public TestThread(int thread, StringBuilder message) {
this.thread=thread;
this.message=message;
start();
}
public void run() {
synchronized(this){
for (int i=0; i<1000000; i++) {
double a=2*2;
}
modifyMessage();
}
}
public synchronized void modifyMessage() {
message.append(thread);
}
}
public class TestMultithreading {
static TestThread[] testThreads = new TestThread[5];
public static void main(String args[]) {
StringBuilder message = new StringBuilder("A");
for (int i=0;i<5;i++)
testThreads[i] = new TestThread(i, message);
for (int i=0;i<5;i++)
try {
testThreads[i].join();
} catch (InterruptedException e) {}
out.println(message);
}
}
I expect this to have a guaranteed output of a string of length 6. However, from time to time I see something like this:
A1034
This means that one of the threads failed to modify the object. Can someone explain me, why this happens and propose a solution for the problem?
You already answered your own question:
When one thread is executing a synchronized method for an object, all
other threads that invoke synchronized methods for the same object
block
The synchronized only block access on the method of the same object, which means that in every thread the modifyMessage() can be called at the same time
What you are looking for is a something like this:
for (int i=0; i<1000000; i++) {
double a=2*2;
}
synchronized(message){
modifyMessage();
}
Now the method is only call once per StringBuilder instance.
Your methods are all synchronizing on a different object (this).
If you change the method to synchronize on a single object, it'll work. For example.
public void modifyMessage() {
synchronized(message) {
message.append(thread);
}
}
I have two Java classes as below...
(1) JavaClass SyncTest: It defines a class (implementing Runnable) and invokes a "synchronized" method (named "call") defined in Class SyncTestCalled
(2) JavaClass SyncTestCalled : There is one synchronized method.
------
After calling from main(), I am thinking it should output something like:
[Two]
[Three]
[One]
But, it outputs something like this (note the open bracket which is not paired in right locations) :
[[[Two]
Three]
One]
What's wrong with the codes? Please help. Thanks a lot!
Here is the code of these two classes...
public class SyncTest implements Runnable {
Thread t;
String name;
SyncTestCalled syncTestCalled;
public SyncTest(String name) {
t = new Thread(this, name);
syncTestCalled = new SyncTestCalled();
this.name = name;
t.start();
}
public void run() {
syncTestCalled.call(this.name);
}
public static void main(String[] args) {
SyncTest syncTest1 = new SyncTest("One");
SyncTest syncTest2 = new SyncTest("Two");
SyncTest syncTest3 = new SyncTest("Three");
}
} // of class SyncTest
public class SyncTestCalled {
public SyncTestCalled() {
// Do nothing
}
synchronized public void call(String message) {
System.out.print("[");
try {
Thread.sleep(1000);
System.out.print(message);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("]");
}
} // of class SyncTestCalled
When you use synchronized as part of the method declaration, Java attempts to acquire the monitor (lock) on the object the method is invoked on. So a method like
synchronized public void call(String message) {
...
}
is equivalent to
public void call(String message) {
synchronized (this) {
...
}
}
In your code, you create three different SyncTestCalled objects and pass each individual one to the different SyncTest instances. In other words, nothing is coordinated. Each call to
syncTestCalled.call(this.name);
is synchronized on a different object and therefore none of the threads need to wait on the others.
It's up to the Thread scheduler who gets where first, so you get output like
[[[Two]
Three]
One]
or
[[[OneThree]
Two]
]
Note that Thread.sleep(long) does not relinquish any monitors the thread currently has.
Only one thread can invoke your call() method on a given instance at any given time. But what you want is atomicity for several calls to System.out.print() methods. For that, you need to acquire a lock on System.out instead:
synchronized (System.out) {
System.out.print('[');
System.out.print(message);
System.out.println(']');
}
Because PrintStream locks on itself, this will prevent other threads from interleaving their own calls to print().
I have a static function like:
public static void foo()
{
//code follows
System.out.println(Thread.currentThread().getName());
//code follows
}
and multiple threads are calling this function concurrently. I have set the names of threads using
Thread.setName(String)
When i execute the code, the print statement will print the name of only one thread. How can i identify the names of all the threads currently executing the foo() function?
EDIT:
public class FooThread extends Thread
{
public FooThread(String name)
{
this.setName(name);
}
#Override public void run()
{
//do something
//do something
Main.foo();
}
}
//Main Class
public class Main
{
public static void main(String[] args)
{
for(int i=0;i<6;++i)
{
new FooThread("Thread"+i).start();
}
}
public static void foo()
{
//do something
while(true)
{
//do something
System.out.println(Thread.currentThread().getName());
}
}
}
You're already showing the name of the Thread that is calling your code. Code that proves this:
public class Foo2 {
public static synchronized void foo() {
System.out.println(Thread.currentThread().getName());
}
public static void main(String[] args) {
int maxCount = 10;
for (int i = 0; i < maxCount; i++) {
Thread thread = new Thread(new Runnable() {
public void run() {
foo();
}
});
thread.setName("Thread " + i);
thread.start();
long sleepTime = 1000;;
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {}
}
}
}
Return:
Thread 0
Thread 1
Thread 2
Thread 3
Thread 4
Thread 5
Thread 6
Thread 7
Thread 8
Thread 9
Your problem lies in code not shown.
Either your method is being called by one and only one thread, or
Or you're giving all your threads the same name.
Again, for a complete solution as to what is actually wrong with your current set up, create and post an sscce similar to what I've posted above. For all we know you could be calling run() on your Threads, and until we can see and reproduce your problem, I don't think that we'll be able to fully understand it.
EDIT
Regarding your SSCCE: Compare the results of the two methods below, foo1() and foo2()
class FooThread extends Thread {
public FooThread(String name) {
this.setName(name);
}
#Override
public void run() {
// do something
// do something
Main.foo1(); // !! Swap comments
// Main.foo2(); // !! Swap comments
}
}
// Main Class
public class Main {
private static final long SLEEP_TIME = 4;
public static void main(String[] args) {
for (int i = 0; i < 6; ++i) {
new FooThread("Thread" + i).start();
}
}
public static void foo1() {
// do something
while (true) {
// do something
synchronized (Main.class) {
System.out.println(Thread.currentThread().getName());
}
try {
Thread.sleep(SLEEP_TIME);
} catch (InterruptedException e) {}
}
}
public static void foo2() {
while (true) {
System.out.println(Thread.currentThread().getName());
}
}
}
If your while loop isn't so tight, but yields the CPU with say a short Thread.sleep, you'll see more of the different threads sharing foo in closer proximity.
But again, your code also proves that your Thread names *are8 being displayed, but that you're only seeing one name likely because that thread is hogging the CPU.
Another option is to get all the Thread stacks and look for all the threads in the foo() This has the benefit of no overhead or extra code, except to capture the information you want.
BTW: Can you make it clearer why do you need this information as I suspect there is a better way to do what you really want?
If you only want to get the count of threads, use a thread-safe counter to store number of threads. Increase the counter when foo() begins, and decrease the counter when foo() exits.
If you need to get the names, use a hash set (or list if there are duplicates of thread names) to store the names: Add the name when foo() begins, and remove the name when foo() exits. Make sure the access to hash set is thread safe. You also need another method to print out the content of the hash set, so you can call it any time to see what are the name of threads executing foo().
You can put the name into a list when the method starts (in a synchronized block) and remove it at the end again.
List allTheNames = Collections.synchronizedList(new ArrayList<String>());
public void foo() {
allTheNames.add(Thread.currentThread().getName());
// now allTheNames contains all the names of all threads currently in this method.
System.out.println(allTheNames.toString());
allTheNames.remove(Thread.currentThread().getName());
}
Of course, if you change the name of the thread in the meantime that wont work, but why would you do so?
You could also store the Thread itself if you need other informations that the name.
I am new to Java. Below is a code as an example of threads and synchronization.
public class A implements Runnable{
public synchronized void run(){
/*
some code here
*/
}
}
public class B {
public static void main(String[] args){
A obj1 = new A();
Thread t = new Thread(obj1);
A obj2 = obj1;
Thread t1 = new Thread(obj2);
t.start();
t1.start();
}
}
Now will this two threads block each other for same lock or will they get two different locks?
Thank you!!
(First, please stick to the Java coding conventions. A class name should always start with a capital letter. No exceptions.)
Only one of the threads will execute the run() method at a time.
The A.run() method is an instance method, and it is declared as synchronized. These two facts mean that it will acquire a lock on this (i.e. the instance of A) before entering the method body, and release it on exiting. In short, run() locks this.
So in your main program you are creating a single A instance and passing it as the target object for two threads. They both need to execute the run() method on the same object, and this cannot happen at the same time ... by the reasoning of the previous paragraph.
This does not necessarily mean that one thread will block the other. It is also possible that the first thread to be started will have completed its run() call before the second thread is ready to try the call. But we can say ... definitively ... that the two threads' calls to run() will NOT overlap in time.
They will block each other, since they're both synchronized on the same object.
For example, this program:
public class Foo
{
public static void main(final String... args)
{
final Runnable r =
new Runnable()
{
public synchronized void run()
{
for(int i = 0; i < 10; ++i)
{
System.out.println(i);
try
{ Thread.sleep(1000L); }
catch(final InterruptedException ie)
{ throw new RuntimeException(ie); }
}
}
};
new Thread(r).start();
new Thread(r).start();
}
}
will print 0 through 9, pausing for a second after number, and then do it again. It will not interlace the two sets of numbers.
Synchronization forces the threads to run in order (block).
Synchronization, by definition, means that a method is run "one at a time". The first thread to be executed (likely "t") will thus complete before the 2nd thread (probably "t1")'s run() method is entered.
To test the synchronization effects:
The best experiment to run will be to fill the run() method with a call to
Thread.sleep(1000);
Then run your code with, and without the "synchronized" keyword, and time the programs execution .
The output of this code is getting intermixing of thread1 and thread0
package oopd;
/**
*
* #author mani deepak
*/
public class Oopd {
/**
* #param args the command line arguments
*/
public static void main(String[] args)
{
// TODO code application logic here
Deepak d,d1;
d=new Deepak();
d1=new Deepak();
Thread t,t1;
t=new Thread(d);
t1=new Thread(d1);
t.start();
t1.start();
}
}
class Deepak implements Runnable
{
#Override
public synchronized void run()
{
String s=Thread.currentThread().getName();
for(int i=0;i<10;i++)
{
try
{
Thread.sleep(100);
}
catch(Exception e)
{
}
System.out.println(s+" "+i);
}
}
}