I am trying to create a simple Java Swing-based application that manually controls two threads which are both trying to continually increment an integer value. The application should be able to 'Start' and 'Stop' either of the threads (both threads incrementing the value simultaneously) and put either of the threads in the critical region (only one thread allowed to increment value).
Here's a screenshot of what I have, so that you may better understand what I am aiming for:
https://i.imgur.com/sQueUD7.png
I've created an "Incrementor" class which does the job of incrementing the int value, but if I try adding the synchronized keyword to the increment() method, I do not get the result I want.
private void increment() {
while (Thread.currentThread().isAlive()) {
if (Thread.currentThread().getName().equals("Thread 1")) {
if (t1Stop.isEnabled()) {
value++;
t1TextField.setText("Thread 1 has incremented value by 1. Current value = " + value + "\n");
}
} else if (Thread.currentThread().getName().equals("Thread 2")) {
if (t2Stop.isEnabled()) {
value++;
t2TextField.setText("Thread 2 has incremented value by 1. Current value = " + value + "\n");
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
Any advice on how to proceed?
I hope I've made it clear what it is I am looking for, if not, let me know and I'll update this post.
your problem is the dreaded thread lock !!
but if I try adding the synchronized keyword to the increment() method, I do not get the result I want.
of course ! Thread manager changes the "Working" thread whenever he feels like it !, and you should post more code here , but from the first look , you are running the same method in both threads , so it will be dropped down to 2 case :-
the good case !
the Thread Manager changes the thread after it finishes calling the increment method(good old win win for both threads ^-^).
the bad case (and this is what you have faced)
imagine that a thread accessed the method and before completing the method the thread managers changes it and when the other method tries to access it find's a big nasty synchronized in it's face with the lock in the other thread !from here is their is no guarantee what will happen but i can assure you that 90% of this cases result's only pleases the thread manager .
The application should be able to 'Start' and 'Stop' either of the threads (both threads incrementing the value simultaneously) and put either of the threads in the critical region (only one thread allowed to increment value).
sorry to break it to you but the thread manager is not-controllable my friend .
but we can suggest a fair amount of thing's to the thread manager , so what you are trying to achieve is not possible at the java thread manager .
and stopping thread's ooky dooky , but starting a thread after stopping it is big NO !!!
from the Thread.start() documentation
It is never legal to start a thread more than once.
In particular, a thread may not be restarted once it has completed
execution.
throws IllegalThreadStateException if the thread was already
started.
here's a very rich link were you can get the topic explained more widely at the oracle's
You can use object-level lock using synchronized keyword.
=> Object-level lock : To synchronize a non static method or block so that it can be accessed by only one thread at a time for that instance. It is used to protect non static data.
Example :
public class ClasswithCriticalSections {
private AtomicInteger count = new AtomicInteger(0);
public synchronized int increment() {
count.incrementAndGet();
return count;
}
}
or
public class ClasswithCriticalSections {
Object lock1 = new Object();
Object lock2 = new Object();
private AtomicInteger count = new AtomicInteger(0);
public int increment() {
synchronized(lock1) {
count.incrementAndGet();
return count;
}
}
public int decrement() {
synchronized(lock2) {
count.addAndGet(-1);
return count;
}
}
}
Related
I have a piece of code that on startup creates a HashMap of key to ReentrantLock.
void constructor() {
this.lockMap = new HashMap<>();
for (int i=0; i<100; i++) {
this.lockMap.put(i, new ReentrantLock(true));
}
}
During concurrent execution, I try to lock the lock inside the lockMap in the following manner:
runConcurrently() {
ii = 10;
if (!lockMap.containsKey(ii)) {
log.error("lock id is not found in the lockMap " + ii);
}
locked = lockMap.get(ii).tryLock();
if (!locked) {
return;
}
runCriticialSection();
lockMap.get(ii).unlock();
}
void runCriticialSection() {
log.info("hello");
log.info("I'm here");
}
so here is what I have seen happen once in while every 4 hours the code is running, in a very rare occurrence.
I see these logs:
hello.
hello.
I'm here.
I'm here.
and then I see this log right after on third time accessing the hasmap on the same key ii =10:
lock id is not found in the map 10.
NullPointerExeception ... trying to access the map.
where I should see in guaranteed ordering:
hello.
I'm here.
hello.
I'm here.
The Hashmap never gets modified during execution at all.
is there an issue with hashmap not being concurrent hashmap? is get, not threadsafe in absence of modifications? I am specifically not using it due to locking slowness in concurrent hasmap. But the hashmap is only created on startup and never modified after. I find it very weird where it seems the lock has been acquired twice and it seems like the element is missing from the map.
There is no concurrency issue with the map itself, if the map is never modified after the constructor. If so, threads will only ever see that final version of the map. Else, the behaviour is undefined.
No exclusive access of the critical section
From your output, it appears that (at least) two threads accessed runCriticialSection simultaneously.
This is due to the fact that you are using a different lock for each value of ii. A lock only excludes another thread from locking it, if that other threads uses that same lock! Thus, threads that do not use the same value of ii, will effortlessly run runCriticialSection simultaneously. That can result in the described output anomaly as shown above, as follows:
Thread 1 executes log.info("hello");
Thread 2 executes log.info("hello");
Thread 1 executes log.info("I'm here");
Thread 2 executes log.info("I'm here");
If you want exclusive access to a section, always use the same lock surrounding that section.
Coding problems
When the check fails that ii maps to a lock, you should not continue but instead return or throw an exception. If you don't, locked = lockMap.get(ii).tryLock(); throws a NullPointerExcetpion, because lockMap.get(ii) returns null.
Between locking the lock and unlocking it, you are running user code, in the form of runCriticalSection. If you change the implementation of that method later and it starts throwing things: your lock will never unlock! Always use try ... finally with a lock.
Fixing these issues, could lead to the following code:
if (!lockMap.containsKey(ii)) {
log.error("lock id is not found in the lockMap " + ii);
return;
}
locked = lockMap.get(ii).tryLock();
if (!locked) {
return;
}
try {
runCriticialSection();
}
finally {
lockMap.get(ii).unlock();
}
Actually, I would just put the lock in a local variable, but that is a matter of opinion.
ReentrantLock lock = lockMap.get(ii);
if (lock == null) {
log.error("lock id is not found in the lockMap " + ii);
return;
}
locked = lock.tryLock();
if (!locked) {
return;
}
try {
runCriticialSection();
}
finally {
lock.unlock();
}
I am trying to get familiar with wait() and notify() methods and I have written a simple class acting like a monitor for a simple producer-consumer excercise where there are N producers and N consumers. Anyway the monitor, as requested in the excercise, can store only 3 items. So the producers must wait; on the contrary if there are 0 items in the monitor the consumers must wait.
public class Monitor {
private List<Integer> items;
private int capacity;
private Object waitProducer;
private Object waitConsumer;
private int counter;
public Monitor() {
this.items = new ArrayList<Integer>();
this.capacity = 3;
this.waitProducer = new Object();
this.waitConsumer = new Object();
this.counter = 0;
}
public void produce() throws InterruptedException {
synchronized (this) {
if (this.items.size() == this.capacity) {
synchronized (this.waitProducer) {
System.out.println("Producer " + Thread.currentThread().getId() + " aspetta");
this.waitProducer.wait(); /***/
}
}
counter++;
System.out.println("Thread " + Thread.currentThread().getId()
+ " produces object " + counter);
this.items.add(counter);
synchronized (this.waitConsumer) {
this.waitConsumer.notify();
}
}
}
public void consume() throws InterruptedException {
synchronized (this) {
if (this.items.size() == 0) {
synchronized (this.waitConsumer) {
this.waitConsumer.wait(); /***/
}
}
System.out.println("Thread " + Thread.currentThread().getId()
+ " consume object " + this.items.get(0));
this.items.remove(0);
synchronized (this.waitProducer) {
this.waitProducer.notify();
}
}
}
}
I think that there is a problem in lines with /***/: infact when the wait() method is invoked then the thread releases the lock on waitProducer (or waitConsumer) but it does not on the Monitor object. That's why when the first produces (of the first consumer) calls wait() then the Monitor object is no more obtainable. Obvioudly the access to the Monitor object must be in mutual exclusion so that to update correctly the list and the counter. So, what is the correct way? Thanks
Only one thread can execute the code inside synchronized blocks at a time.
Also, one must gain an exclusive lock on an object (via synchronized(object)) when calling wait() on that object.
This means, the unlocking/unblocking/notify code must be accessible to other threads outside of original block which called wait(). Otherwise, execution will wait forever.
In your code no other thread can reach this.waitConsumer.notify(); while one thread waits on this.waitProducer.wait();. Because all of it is also enclosed in a synchronized(this) block, other threads will keep contesting for locking on this.
#james large What do you mean that two threads can be synchronized in the same block if they are synchronized on different objects?
Suppose you have a synchronized block that looks like this:
synchronized(obj) {
...body of synchronized block...
}
...whatever happens next...
When Java thread T executes that statement, it starts by evaluating the expression, obj. That expression must either return null, or it must return a reference to an object. If it's null, then a NullPointerException will be thrown. Otherwise, thread T will attempt to lock the object.
No two threads can ever lock the same object at the same time. If the object already was locked by some other thread, then thread T will be unable to proceed until the object is unlocked.
When thread T finally is able to lock the object, it will execute the body of the synchronized block, and then it will unlock the object and move on to whatever happens next.
The important concept here is the expression, obj. Suppose that thread T evaluates obj, gets a reference to object O, locks it, and enters the synchronized block. Then thread U comes along, evaluates obj, gets a different object, P. Thread U will lock object P, and will be able to enter the synchronized block while thread T still is in there at the same time.
So how can that happen?
When it's intended, it might look like this:
class MyClass {
private final Object lock = new Object();
void foobar() {
synchronized(lock) { ... }
}
}
If thread T and thread U are operating on different instances of MyClass, then each instance will have its own lock object. Usually, in this case, the body of the synchronized block will only operate on other instance variables of MyClass. Since the two threads are operating on different data, there is no harm in them both being in the same synchronized block at the same time.
The purpose of synchronization is not to keep two threads out of the same method at the same time: The purpose is to keep two threads from operating on the same data at the same time.
Sometimes a newbie programmer writes this:
static Integer count = new Integer(0);
...
synchronized(count) {
count += 1;
...operate on static data...
}
This is almost always a mistake. When thread T enters the block, it will synchronize on the Integer object that is referenced by the static variable count. But then the next thing it does is update count to refer to a different Integer object. Then along comes thread U. U synchronizes on the new count, and both threads are in the same block, operating on the same static data when they should not.
I was trying to implement something similar to Java's bounded BlockingQueue interface using Java synchronization "primitives" (synchronized, wait(), notify()) when I stumbled upon some behavior I don't understand.
I create a queue capable of storing 1 element, create two threads that wait to fetch a value from the queue, start them, then try to put two values into the queue in a synchronized block in the main thread. Most of the time it works, but sometimes the two threads waiting for a value start seemingly waking up each other and not letting the main thread enter the synchronized block.
Here's my (simplified) code:
import java.util.LinkedList;
import java.util.Queue;
public class LivelockDemo {
private static final int MANY_RUNS = 10000;
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < MANY_RUNS; i++) { // to increase the probability
final MyBoundedBlockingQueue ctr = new MyBoundedBlockingQueue(1);
Thread t1 = createObserver(ctr, i + ":1");
Thread t2 = createObserver(ctr, i + ":2");
t1.start();
t2.start();
System.out.println(i + ":0 ready to enter synchronized block");
synchronized (ctr) {
System.out.println(i + ":0 entered synchronized block");
ctr.addWhenHasSpace("hello");
ctr.addWhenHasSpace("world");
}
t1.join();
t2.join();
System.out.println();
}
}
public static class MyBoundedBlockingQueue {
private Queue<Object> lst = new LinkedList<Object>();;
private int limit;
private MyBoundedBlockingQueue(int limit) {
this.limit = limit;
}
public synchronized void addWhenHasSpace(Object obj) throws InterruptedException {
boolean printed = false;
while (lst.size() >= limit) {
printed = __heartbeat(':', printed);
notify();
wait();
}
lst.offer(obj);
notify();
}
// waits until something has been set and then returns it
public synchronized Object getWhenNotEmpty() throws InterruptedException {
boolean printed = false;
while (lst.isEmpty()) {
printed = __heartbeat('.', printed); // show progress
notify();
wait();
}
Object result = lst.poll();
notify();
return result;
}
// just to show progress of waiting threads in a reasonable manner
private static boolean __heartbeat(char c, boolean printed) {
long now = System.currentTimeMillis();
if (now % 1000 == 0) {
System.out.print(c);
printed = true;
} else if (printed) {
System.out.println();
printed = false;
}
return printed;
}
}
private static Thread createObserver(final MyBoundedBlockingQueue ctr,
final String name) {
return new Thread(new Runnable() {
#Override
public void run() {
try {
System.out.println(name + ": saw " + ctr.getWhenNotEmpty());
} catch (InterruptedException e) {
e.printStackTrace(System.err);
}
}
}, name);
}
}
Here's what I see when it "blocks":
(skipped a lot)
85:0 ready to enter synchronized block
85:0 entered synchronized block
85:2: saw hello
85:1: saw world
86:0 ready to enter synchronized block
86:0 entered synchronized block
86:2: saw hello
86:1: saw world
87:0 ready to enter synchronized block
............................................
..........................................................................
..................................................................................
(goes "forever")
However, if I change the notify() calls inside the while(...) loops of addWhenHasSpace and getWhenNotEmpty methods to notifyAll(), it "always" passes.
My question is this: why does the behavior vary between notify() and notifyAll() methods in this case, and also why is the behavior of notify() the way it is?
I would expect both methods to behave in the same way in this case (two threads WAITING, one BLOCKED), because:
it seems to me that in this case notifyAll() would only wake up the other thread, same as notify();
it looks like the choice of the method which wakes up a thread affects how the thread that is woken up (and becomes RUNNABLE I guess) and the main thread (that has been BLOCKED) later compete for the lock — not something I would expect from the javadoc as well as searching the internet on the topic.
Or maybe I'm doing something wrong altogether?
Without looking too deeply into your code, I can see that you are using a single condition variable to implement a queue with one producer and more than one consumer. That's a recipe for trouble: If there's only one condition variable, then when a consumer calls notify(), there's no way of knowing whether it will wake the producer or wake the other consumer.
There are two ways out of that trap: The simplest is to always use notifyAll().
The other way is to stop using synchronized, wait(), and notify(), and instead use the facilities in java.util.concurrent.locks.
A single ReentrantLock object can give you two (or more) condition variables. Use one exclusively for the producer to notify the consumers, and use the other exclusively for the consumers to notify the producer.
Note: The names change when you switch to using ReentrantLocks: o.wait() becomes c.await(), and o.notify() becomes c.signal().
There appears to be some kind of fairness/barging going on using intrinsic locking - probably due to some optimization. I am guessing, that the native code checks to see if the current thread has notified the monitor it is about to wait on and allows it to win.
Replace the synchronized with ReentrantLock and it should work as you expect it. The different here is how the ReentrantLock handles waiters of a lock it has notified on.
Update:
Interesting find here. What you are seeing is a race between the main thread entering
synchronized (ctr) {
System.out.println(i + ":0 entered synchronized block");
ctr.addWhenHasSpace("hello");
ctr.addWhenHasSpace("world");
}
while the other two thread enter their respective synchronized regions. If the main thread does not get into its sync region before at least one of the two, you will experience this live-lock output you are describing.
What appears to be happening is that if both the two consumer threads hit the sync block first they will ping-pong with each other for notify and wait. It may be the case the JVM gives threads that are waiting priority to the monitor while threads are blocked.
I have this piece of code
public MultiThreadedSum(ArrayBuffer ArrayBufferInst)
{
this.ArrayBufferInst = ArrayBufferInst;
Sum = 0;
Flag = false;
StopFlag = false;
}
public synchronized void Sum2Elements()
{
while(Flag)
{
try {wait();}
catch (InterruptedException e){}
}
Flag = true;
if (StopFlag)
{
notifyAll();
return;
}
System.out.println("Removing and adding 2 elements.");
Sum = ArrayBufferInst.Sum2Elements();
notifyAll();
}
public synchronized void InsertElement()
{
while(!Flag)
{
try {wait();}
catch (InterruptedException e){}
}
Flag = false;
if (StopFlag)
{
notifyAll();
return;
}
System.out.println("Inserting the sum.");
ArrayBufferInst.InsertElement(Sum);
if (ArrayBufferInst.RetunrSize() == 1)
{
StopFlag = true;
}
System.out.println(ArrayBufferInst);
notifyAll();
}
As you can see, I set the Flag to be false first so one of the threads can enter the Sum2Elements method and change it to true and by that, making everyone wait.
I know that in synchronized code, only one thread can do its thing, well here I have two synchronized methods, does it mean that 2 threads are trying to conduct this methods after each notifyall?
And if so, is it not possible for one thread to enter Sum2Elements, change the flag to true before the other thread enters InsertElement, and by that skipping the while loop?
Thanks
Only one thread can hold the lock of the object. And then it's only that thread that can enter the synchronized methods on that object.
The thread can however release the lock without returning from the method, by calling Object.wait().
So your code looks good!
does it mean that 2 threads are trying to conduct this methods after each notifyall?
Ans : It is very much possible for two threads to be in two of your synchronized methods since you are calling wait().
is it not possible for one thread to enter Sum2Elements, change the flag to true before the other thread enters InsertElement, and by that skipping the while loop?
Ans : Yes this is possible again for the same reason specified above.
Locks are obtained on objects of a class & not on any particular synchronized method.
Both the methods are instance methods. So if one of the threads have entered any synchronized method for an object, A say, then any other thread cant enter any synchronized method for that object until the running thread doesnt call notifyAll() method. At that stage all the waiting threads compete to become active but it depends on the thread scheduler to choose a thread which is to become active.
If you want that two different threads should access these synchronized methods simultaneously then the 2 threads should operate on 2 different objects of the class.
Only one thread can execute one of two method at a time because both are synchronized though order is undefined
As I said one method can be executed by one thread at a time only unless executing thread release the lock by callingwait method and other thread get the lock and execute other synchronized method which make your both the statements possible.
I have a java applet. A class inside that applet is creating a thread to do some work, waiting 30 seconds for that work to complete, if its not completed in 30 secs it sets a Boolean to stop the thread. The wait and Boolean change are in a synchronized block, Is this necessary considering there is no other thread running aside from these 2.
System.out.println("Begin Start Session");
_sessionThread = new SessionThread();
_sessionThread.start();
synchronized (_sessionThread)
{
_sessionThread.wait(30000);
_sessionThread._stopStartSession = true;
}
Why couldn't I just do this instead.
System.out.println("Begin Start Session");
_sessionThread = new SessionThread();
_sessionThread.start();
_sessionThread.wait(30000);
_sessionThread._stopStartSession = true;
SessionThread run method. Invokes a JNI method to call a dll to open a program window.
public void run()
{
try
{
startExtraSession();
}
catch (Throwable t)
{
t.printStackTrace();
}
notify();
}
private native void openSessionWindow(String session_file);
private void startExtraSession()
{
final String method_name = "startExtraSession";
String title = _sessionInfo._title;
long hwnd = 0;
openSessionWindow(_sessionInfo._configFile);
try
{
//Look for a window with the predefined title name...
while ((hwnd = nativeFindWindow(title)) == 0 && !_stopStartSession)
{
Thread.sleep(500);
}
}
catch(Throwable t)
{
t.printStackTrace();
}
}
1. Is the synchronized really needed?
2. Is there a better way to accomplish this aside from using threads?
A given thread is required to own a lock on a object to be able to call wait(long) on it. This is achieved by using a synchronized block on the said object.
See J2SE specification on using wait.
Acquiring a lock/monitor in java can be done in various ways:
In a synchronized (non-static) method, the thread owns a monitor on the object referenced by this.
In a static synchronized method, the thread owns a monitor on the Class<?> descriptor for the class that defines the said method.
In a synchronized(x) block, the thread owns a monitor on x.
That lock will be released if:
You get outside of the synchronized code block (be it a method, static method, or explicit block).
You have called wait() or one of its variations (and you'll re-acquire it just before the method returns).
Both these two lists may omit specific cases but should cover at least a large portion of the typical use cases.
There's a very simple reason that you need synchronized to call wait
The synchronized makes sure that nobody is calling notify or notifyAll at the same time you're calling wait
For example: Thread 1
synchronized( obj )
{
triggerActionOnThread2();
obj.wait();
}
Thread 2 (triggered by triggerActionOnThread2)
...
synchronized( obj )
{
obj.notify();
}
If you don't have the synchronized blocks, then the notify might happen before (or during) the wait, and then the wait misses the notify, and you can hang Thread 1.
Imagine the above blocks of code without the synchronized blocks, and imagine if Thread 2 is executed all the way through the notify before the wait gets called.
BTW, I ask this very question on interviews for Java engineers when the job will involve multithreaded programming.
Can you please post SessionThread code? You cannot wait if you don't own the lock, so you need synchronized (_sessionThread) to do _sessionThread.wait(30000); Not sure what's with _sessionThread._stopStartSession = true;
If the boolean is the only shared state between the threads, declaring the boolean transient will guarantee that changes to it are seen between the threads as would a synchronization block around access to the boolean.