I have 3 classes: Main, Caller and CallMe. Caller implements Runnable. I pass to Caller constuctor a pointer to instance of CallMe and a message that Caller pass to method of instance of CallMe which print the message. Next, I start a thread.
In Main I create 3 instances of Caller and I except that here it will be printed:
[Welcome]
[to synchronized]
[world!]
But I get the following result:
[Welcome]
[world!]
[to synchronized]
Why?
There is the code:
Main.java
public class Main {
public static void main(String[] args) {
CallMe target = new CallMe();
Caller ob1 = new Caller(target, "Welcome");
Caller ob2 = new Caller(target, "to synchronized");
Caller ob3 = new Caller(target, "world!");
try {
ob1.thread.join();
ob2.thread.join();
ob3.thread.join();
} catch (InterruptedException exc) {
System.out.println(exc);
}
}
}
Caller.java
public class Caller implements Runnable {
String message;
CallMe target;
Thread thread;
public Caller(CallMe target, String message) {
this.target = target;
this.message = message;
this.thread = new Thread(this);
this.thread.start();
}
public void run() {
synchronized (target) {
target.call(message);
}
}
}
CallMe.java
public class CallMe {
public void call(String msg) {
System.out.print("[" + msg);
try {
Thread.sleep(1000);
} catch (InterruptedException exc) {
System.out.println(exc);
}
System.out.println("]");
}
}
The three instantiations of Caller in your main method probably all happen within one time slice, i.e. without yielding to another thread. This results in all three threads being created and placed into the runnable state. After that, threads can be scheduled in any order, so you just got unlucky.
If you want threads to execute in a specific order you need to provide the interlocking logic yourself.
Related
In the following code,
public class Callme {
public Callme() {
// TODO Auto-generated constructor stub
}
void callA(String msg) throws InterruptedException
{
synchronized (this) {
System.out.print("["+msg);
Thread.sleep(1000);
}
System.out.println("]");
}
void callB(String msg) throws InterruptedException
{
synchronized (this) {
System.out.print("{"+msg);
Thread.sleep(1000);
}
System.out.println("}");
}
void callC(String msg) throws InterruptedException
{
synchronized (this) {
System.out.print("("+msg);
Thread.sleep(1000);
}
System.out.println(")");
}
}
Somewhere else:
public class Caller implements Runnable {
public char msg;
public Callme target;
public Thread t;
public Caller(char msg, Callme target) {
this.msg = msg;
this.target = target;
t= new Thread(this);
}
#Override
public void run() {
try {
switch (msg) {
case '[':
target.callA("Hello");
break;
case '{':
target.callB("Hello");
break;
case '(':
target.callC("Hello");
break;
default:
break;
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Somewhere else:
Callme target = new Callme();
Caller ob1 = new Caller('[', target);
Caller ob2 = new Caller('{', target);
Caller ob3 = new Caller('(', target);
ob1.t.start();
ob2.t.start();
ob3.t.start();
Assuming callA runs first, after its synchronizedstatement is executed, in my trials, always ob1 next step is executed.
I thought sometimes ob2 synchronized step should be executed before that(at least sometimes).
Actual Output:
[Hello]
{Hello}
(Hello)
Expected Output:
[Hello(Hello]
)
{Hello}
Of course the order of {,[ and ( can vary and is not predictable.
Any job is restricted to adquire
synchronized (this) {
<<job>>
}
<<after>>
and any job must run <<job>> before <<after>>.
To be multiple <<after>> interleaved (<<job>> is impossible), one <<after>> must be blocked at least, until other later <<job>> and <<after>> will be executed. Using your code is very unlikely (<<after>> take the time to print one character but <<job>> take one second).
No matter how, how many and when the methods are called.
To produce the desired behavior, you must to add the blocking after the synchronized code and before the <<after>> code.
class Call {
public Call() {}
private static void delay(int ms) {
try {
Thread.sleep(ms);
} catch (InterruptedException e) {
// keep out!
}
}
private void call(char a, String msg, char b) {
synchronized (this) {
System.out.print(a);
System.out.print(msg);
delay(100);
}
delay(ThreadLocalRandom.current().nextInt(10) * 10); // probability
System.out.println(b);
}
void callA(String msg) { call('[', msg, ']'); }
void callB(String msg) { call('{', msg, '}'); }
void callC(String msg) { call('(', msg, ')'); }
}
public class Callme {
static Call call = new Call();
static List<Consumer<String>> calls = asList(call::callA, call::callB, call::callC);
static void randomCall() {
calls.get(ThreadLocalRandom.current().nextInt(calls.size())).accept("Hello!");
}
public static void main(String... args) {
IntStream.range(0, 50).forEach(ignore -> new Thread(Callme::randomCall).start());
}
}
With outout:
(Hello!)
(Hello!)
)
{Hello!{Hello!}
{Hello!}
}
[Hello!(Hello!]
)
(Hello![Hello!)
{Hello!]
(Hello!}
[Hello!)
[Hello!]
]
(Hello![Hello!)
(Hello!]
[Hello!)
...
I would say the expected output is
[Hello]
{Hello}
(Hello)
Complete messages are expected because when leaving a synchronized block the code proceeds and immediately prints the closing character. Other threads do not continue that fast, first of all they have to get scheduled and then acquire the lock for the synchronized block, these steps take time
Thread.start() starts an OS-level thread (https://github.com/openjdk-mirror/jdk7u-jdk/blob/master/src/share/classes/java/lang/Thread.java#L673, https://github.com/openjdk-mirror/jdk7u-jdk/blob/master/src/share/classes/java/lang/Thread.java#L705, https://github.com/openjdk-mirror/jdk7u-jdk/blob/master/src/share/native/java/lang/Thread.c#L44, https://github.com/openjdk-mirror/jdk7u-hotspot/blob/master/src/share/vm/prims/jvm.cpp#L2634, https://github.com/openjdk-mirror/jdk7u-hotspot/blob/master/src/share/vm/runtime/thread.cpp#L420, the chain ending with a system-dependent os::start_thread(thread); line), so ultimately it is up to the operating system how fast and in what order the threads will run, but typically they start running soon and in the order they have been requested to start
synchronized uses object monitors, and they build a list of the threads which are waiting for them (https://github.com/openjdk-mirror/jdk7u-hotspot/blob/master/src/share/vm/runtime/objectMonitor.cpp#L186 is the file, and the code is a bit out of this world, but the list itself is a linked list - well, a circular, doubly-linked one -, _waitSet, managed via the add/dequeue methods starting from https://github.com/openjdk-mirror/jdk7u-hotspot/blob/master/src/share/vm/runtime/objectMonitor.cpp#L2251). So notify() and notifyAll() walk through that list and wake up other threads in a deterministic order.
I have two classes, The first one is in charge of creating threads, then those threads need to be notified from the second class
Problem: I cannot find created threads from the second class, getThreadByName() always return null, Any Idea?.
FirstClass
public class class1{
protected void createThread(String uniqueName) throws Exception {
Thread thread = new Thread(new OrderSessionsManager());
thread.setName(uniqueName);
thread.start();
}
}
OrderSessionManager
public class OrderSessionsManager implements Runnable {
public OrderSessionsManager() {
}
#Override
public void run() {
try {
wait();
}catch(Exception e) {
e.printStackTrace();
}
}
SecondClass
public class class2{
protected void notifyThread(String uniqueName) throws Exception {
Thread thread = Utils.getThreadByName(uniqueName);
thread.notify();
}
}
Utils
public class Utils{
public static Thread getThreadByName(String threadName) {
ThreadGroup currentGroup = Thread.currentThread().getThreadGroup();
int noThreads = currentGroup.activeCount();
Thread[] threads = new Thread[noThreads];
currentGroup.enumerate(threads);
List<String>names = new ArrayList<String>();
for (Thread t : threads) {
String tName = t.getName().toString();
names.add(tName);
if (tName.equals(threadName)) return t;
}
return null;
}
}
There are several issues with your code:
1) It breaks Java Code Conventions: class name must start with a
capital letter
2) wait() method must be called by a thread who owns the object's monitor
so you must use something like:
synchronized (this) {
wait();
}
3) notify() method must be called by a thread who owns the object's monitor and by the same object as wait(), in your case OrderSessionsManager's instance.
4) Since you do not specify a ThreadGroup, the thread gets it's ThreadGroup from it's parent. The following code works as expected:
public class Main {
public static void main(String[] args) {
class1 c1 = new class1();
try {
c1.createThread("t1");
} catch (Exception e) {
e.printStackTrace();
}
Thread thread = Utils.getThreadByName("t1");
System.out.println("Thread name " + thread.getName());
}
}
but this happens only because the t1 thread is in the same group as the main thread.
This question already has answers here:
Java Wait and Notify: IllegalMonitorStateException
(2 answers)
Closed 4 years ago.
Was trying to practice producer and consumer using a simple counter in java.
Not sure why I am getting a Illegal Monitor State exception on this piece of code.
I have counter rest and counter consume methods which run in their own thread.
The counter itself is a static int volatile field .
The counter class also gives you a lock to
If I change the wait naotify to the following:
Counter.lock.notify();
Counter.lock.wait();
The code works. Dosen't wait() and notify() automatically takes the reference of the lock synchronize is on?
Producer Class
package multithreading;
public class CounterProducer implements Runnable {
public void run() {
try { incrCounter(); } catch (InterruptedException e) { e.printStackTrace(); }
}
public void incrCounter() throws InterruptedException {
while (true) {
synchronized (Counter.lock) {
if (Counter.counter < 1) {
System.out.println("Counter Reset");
Counter.counter = 10;
notify();
wait();
}
}
}
}
}
Consumer Class
package multithreading;
public class CounterConsumer implements Runnable {
public void run() {
try { consumeCounter(); } catch (InterruptedException e) { e.printStackTrace(); }
}
public void consumeCounter() throws InterruptedException {
while (true) {
synchronized (Counter.lock) {
if (Counter.counter > 0) {
System.out.println("Consumed");
Counter.counter--;
notify();
wait();
}
}
}
}
}
The Counter
public class Counter {
public static volatile int counter;
public static final Object lock = new Object();
}
The Counter
public class CounterRunner {
public static void main(String[] args) {
Thread con = new Thread(new CounterConsumer());
Thread prod = new Thread(new CounterProducer());
con.start();
prod.start();
}
}
The Runner
public class CounterRunner {
public static void main(String[] args) {
Thread con = new Thread(new CounterConsumer());
Thread prod = new Thread(new CounterProducer());
con.start();
prod.start();
}
}
If I change the wait naotify to the following, the code works:
Counter.lock.notify();
Counter.lock.wait();
Every Java method is either a static method of some class or an instance method of some object. If you see a method call that does not contain an explicit class name or object reference, then it is an implicit call to a method belonging to the this object.
That is to say, notify() means the same thing as this.notify(), and wait() means this.wait().
this, refers to the CounterProducer instance when it appears in your CounterProducer.incrCounter() method, and it refers to the CounterConsumer instance when it appears in your CounterConsumer.consumeCounter() method.
SYNCHRONIZATION
I have declared a class b which has a synchronized method which is accessed in class c:
class b {
String msg;
public synchronized void foo() {
System.out.print("[" + msg);
try {
Thread.sleep(1000); // Threads go to sleeep
} catch (InterruptedException e) {
System.out.println("Caught" + e);
}
System.out.println("]");
}
}
class a implements Runnable {
b ob;
Thread t;
a(String msg, b obb) {
ob = obb;
ob.msg = msg;
t = new Thread(this); // creating a thread
t.start();
}
public void run() {
ob.foo(); // calling method of class b
}
public static void main(String... a) {
b obb = new b();
a ob = new a("Hello", obb); /* PASSING */
a ob1 = new a("Synch", obb); /* THE */
a ob2 = new a("World", obb);/* MESSAGE */
try {
ob.t.join();
ob1.t.join();
ob2.t.join();
} catch (InterruptedException e) {
System.out.println("Caught" + e);
}
}
}
I am expecting the output:
[Hello]
[Synch]
[World]
But the code gives:
[World]
[World]
[World]
Help me with some suggestions. I am a naive JAVA user.
use the following code to get the expected answer.
class b {
// String msg;
public void foo(String msg) {
System.out.print("[" + msg);
try {
Thread.sleep(1000); // Threads go to sleeep
} catch (InterruptedException e) {
System.out.println("Caught" + e);
}
System.out.println("]");
}
}
public class Threading implements Runnable {
b ob;
String msg;
Thread t;
Threading(String message, b obb) {
ob = obb;
msg = message;
t = new Thread(this); // creating a thread
t.start();
}
public void run() {
synchronized (ob) {
ob.foo(msg); // calling method of class b
}
}
public static void main(String... a) {
b obb = new b();
Threading ob = new Threading("Hello", obb); /* PASSING */
Threading ob2 = new Threading("World", obb); /* THE */
Threading ob1 = new Threading("Synch", obb);/* MESSAGE */
try {
ob.t.join();
ob1.t.join();
ob2.t.join();
} catch (InterruptedException e) {
System.out.println("Caught" + e);
}
}
}
In the code you have set ob.msg=msg; msg gets overridden by the threads. So you have the same message for all the Threads.
In the constructor of each Thread of class a you are passing the same object of class b. Now all three threads are setting the value of msg of the instance of class b. So one value overrides the other. What you have is the value set by last thread i.e. World.
IMO: Save the msg as an instance variable in each thread and pass it to the foo method as a parameter.
And please follow Java naming convention i.e. Camel Casing
First of all reformat your code. It is very hard to read.
Second when you call ob.msg = msg; it overrites msg value in ob and as it is not synchronized so you cannot actually predict what the output will be.
public class Common {
public synchronized void synchronizedMethod1() {
System.out.println("synchronizedMethod1 called");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("synchronizedMethod1 done");
}
public void method1() {
System.out.println("Method 1 called");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Method 1 done");
}
}
public class MyThread extends Thread {
private int id = 0;
private Common common;
public MyThread(String name, int no, Common object) {
super(name);
common = object;
id = no;
}
public void run() {
System.out.println("Running Thread" + this.getName());
try {
if (id == 0) {
common.synchronizedMethod1();
} else {
common.method1();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Common c = new Common();
MyThread t1 = new MyThread("MyThread-1", 0, c);
MyThread t2 = new MyThread("MyThread-2", 1, c);
t1.start();
t2.start();
}
}
Output:
Running ThreadMyThread-1
synchronizedMethod1 called
Running ThreadMyThread-2
Method 1 called
synchronizedMethod1 done
Method 1 done
I would like to find a way to prevent method1() from running when i called synchronizedMethod1. Unless I'm mistaken all methods are called and Java compiles them during and before runtime regardless if it's synchronized or not.
Should i have used a Lock object instead and/or not also make method1() a synchronized method?
I would like to find a way to prevent method1() from running when i called synchronizedMethod1
The easiest way to do this is to make method1() also be synchronized. This will mean that both methods will cause a lock on the instance of Common that they are calling. Only one thread will be able to either be calling synchronizedMethod1() or method1().
Unless I'm mistaken all methods are called and Java compiles them during and before runtime regardless if it's synchronized or not.
I don't understand this question. You really should not have to worry about the compilation or optimization phase of the JVM.
Should i have used a Lock object instead?
Usually making a method synchronized is considered not as good as using a private final lock object. Lock objects just allow you to be more fine grained in your locks. For example, with method locking, log messages and other statements that do not need protection will be synchronized as well. But if the goal is to lock the entire method then synchronizing the methods is fine.
If you want method1 and synchronizedMethod1 to be mutually exclusive then you need to guard them with the same lock. Whether this is using a Lock or simply calling synchronize on the same Object instance, the outcome is roughly the same.
On the off chance you want multiple threads to be allowed to execute method1 but not when synchronizedMethod1 is being invoked, you need a ReadWriteLock to accomplish that.
public class Common {
ReadWriteLock rwLock = new ReentrantReadWriteLock();
public void synchronizedMethod1() {
rwLock.writeLock().lock();
try {
System.out.println("synchronizedMethod1 called");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("synchronizedMethod1 done");
} finally {
rwLock.writeLock().unlock();
}
}
public void method1() {
rwLock.readLock().lock();
try {
System.out.println("Method 1 called");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Method 1 done");
} finally {
rwLock.readLock().unlock();
}
}
}