Handling if thread could not enter synchronized(this) block - java

I am working on a Robotic Analog to digital button listener.
Where There is a synchronized (this) block when the action performed.
public void Init() {
new Timer(200, taskPerformer).start();
)
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent e) {
//not synchronized code
synchronized (this) {
//synchronized code
}
}
}
Now my question is How can I understand which Thread Failed to enter that block?
Is there any way so that I can handle those threads. Similar to the if-else , can I handle those thread who could not entered.
Edit: simply want to print("Could not Enter The Block"); How can I do that.?
Thanks.

you can lock on an Object (instead of this) which is shared across group of Threads where you need real synchronization
lock object
Object lockGroup1 = new Object();
Thread that holds it
class MyThread implements Runnable {
Object lock;
public MyThread(Object lock){
this.lock = lock;
}
// other stuff ofcourse
}
and
MyThread thread1 = new MyThread(lock1);
Updates based on Comments
Set<Long> waitingThreads = Collections.synchronizedSet(new HashSet<Long>());
public void myMethod() {
waitingThreads.add(Thread.currentThread().getId());
synchronized (this){
waitingThreads.remove(Thread.currentThread().getId());
}
}

Related

Possibility of deadlock with two locks?

Can this code deadlock with thread 1 calling one and thread 2 calling two. That is, can the acquisition of the inner lock be reordered to before the acquisition of the outer one (from the POV of the other thread)?
private final Object foo = new Object();
synchronized void one() {
// ...
synchronized(this.foo) {
// ...
}
// ...
}
synchronized void two() {
// ...
synchronized(this.foo) {
// ...
}
// ...
}
No, this will not deadlock.
When synchronized methods are called the intrinsic lock of this is locked before the method’s body is executed. Here either thread 1 or thread 2 will get to run its method, and the other one will not be able to lock on the intrinsic lock of this.foo so the owner of the lock of this will be able to lock this.foo.
So for with a Simple Test :
class LockTest implements Runnable {
public final Object foo = new Object();
boolean runOne;
public LockTest(boolean runOne) {
this.runOne = runOne;
}
synchronized void one() {
System.out.println("runnin one function");
synchronized(this.foo) {
try {
System.out.println("Enter Sleep function one");
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
synchronized void two() {
System.out.println("running two function");
synchronized(this.foo) {
try {
System.out.println("enter sleep function two");
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
#Override
public void run() {
if(runOne)
one();
else
two();
}
}
With this in a Main class :
while (true)
{
LockTest document2 = new LockTest(true);
LockTest document3 = new LockTest(false);
Thread tread1 = new Thread(document2);
Thread tread2 = new Thread(document3);
tread1.start();
tread2.start();
a++;
if(a==10)
break;
}
We are not locking and even watching with a Thread Dump everything is working Fine. Why? Because every time we are initializating a new Thread with a new object foo. But if that object is declared as static it will be a lock and the others threads need to wait. So from my test and POV. No, it can't be deadlocked.

Deadlock when calling two synchronized method

class Downloader extends Thread {
private InputStream in;
private OutputStream out;
private ArrayList<ProgressListener> listeners;
public Downloader(URL url, String outputFilename) throws IOException {
in = url.openConnection().getInputStream();
out = new FileOutputStream(outputFilename);
listeners = new ArrayList<ProgressListener>();
}
public synchronized void addListener(ProgressListener listener) {
listeners.add(listener);
}
public synchronized void removeListener(ProgressListener listener) {
listeners.remove(listener);
}
private synchronized void updateProgress(int n) {
for (ProgressListener listener: listeners)
listener.onProgress(n);
}
public void run() {
int n = 0, total = 0;
byte[] buffer = new byte[1024];
try {
while((n = in.read(buffer)) != -1) {
out.write(buffer, 0, n);
total += n;
updateProgress(total);
}
out.flush();
} catch (IOException e) { }
}
}
The above code is from the book "seven concurrency models in seven weeks". The book says the above code is having potential for the deadlock as the the synchronized method updateProgress calls a alien method[onProgress] that might acquire another lock.
Since we acquire two locks without right order, the deadlock might occur.
Can anyone explain how the deadlock happens in the above scenario?
Thanks in advance.
It's best to make the objects you use with synchronized private.
Since you synchronize on the Downloader, you don't know whether other threads synchronize on the Downloader too.
The following listener causes a deadlock:
MyProgressListener extends ProgressListener {
public Downloader downloader;
public void onProgress(int n) {
Thread t = new Thread() {
#Override
public void run() {
synchronized(downloader) {
// do something ...
}
}
};
t.start();
t.join();
}
}
Code that deadlocks:
Downloader d = new Downloader(...);
MyProgressListener l = new MyProgressListener();
l.downloader = d;
d.addListener(l);
d.run();
The following will happen if you run that code:
the main thread reaches the updateProgress and aquires a lock on the Downloader
the MyProgressListener's onProgress method is called and the new thread t is started
the main thread reaches t.join();
In this situation the main thread cannot procede until t is finished, but for t to finish, the main thread would have to release it's lock on the Downloader, but that won't happen since the main thread can't procede -> Deadlock
First off, recall that the keyword synchronized, when applied to a a class, implies locking the whole object this method belongs to. Now, let's sketch out another couple of objects triggering the deadlock:
class DLlistener implements ProgressListener {
private Downloader d;
public DLlistener(Downloader d){
this.d = d;
// here we innocently register ourself to the downloader: this method is synchronized
d.addListener(this);
}
public void onProgress(int n){
// this method is invoked from a synchronized call in Downloader
// all we have to do to create a dead lock is to call another synchronized method of that same object from a different thread *while holding the lock*
DLthread thread = new DLThread(d);
thread.start();
thread.join();
}
}
// this is the other thread which will produce the deadlock
class DLThread extends Thread {
Downloader locked;
DLThread(Downloader d){
locked = d;
}
public void run(){
// here we create a new listener, which will register itself and generate the dead lock
DLlistener listener(locked);
// ...
}
}
One way to avoid the dead lock is to postpone the work done in addListener by having internal queues of listeners waiting to be added/removed, and have Downloader taking care of those by itself periodically. This ultimately depends on Downloader.run inner working of course.
Probably the problem in this code:
for (ProgressListener listener: listeners)
listener.onProgress(n);
When one thread, which holds a lock, calls an external method
like this one (onProgress) then you cannot guarantee that
implementation of this method won't try to obtain other lock,
which could be held by different thread. This may cause a deadlock.
Here's a classic example that shows the kind of hard-to-debug problems the author is trying to avoid.
The class UseDownloader is created and downloadSomething is called.
As the download progresses, the onProgress method is called. Since this is called from within the synchronized block, the Downloader motinor is locked. Inside our onProgress method, we need to lock our own resource, in this case lock. So when we are trying to synchronize on lock we are holding the Downloader monitor.
If another thread has decided that the download should be canceled, it will call setCanceled. This first tests done so it synchronized on the lock monitor and then calls removeListener. But removeListener requires the Downloader lock.
This kind of deadlock can be hard to find because it doesn't happen very often.
public static final int END_DOWNLOAD = 100;
class UseDownloader implements ProgressListener {
Downloader d;
Object lock = new Object();
boolean done = false;
public UseDownloader(Downloader d) {
this.d = d;
}
public void onProgress(int n) {
synchronized(lock) {
if (!done) {
// show some progress
}
}
}
public void downloadSomething() {
d.addListener(this);
d.start();
}
public boolean setCanceled() {
synchronized(lock) {
if (!done) {
done = true;
d.removeListener(this);
}
}
}
}
The following example leads to a deadlock because the MyProgressListener tries to acquire the Downloader lock while it's already acquired.
class MyProgressListener extends ProgressListener {
private Downloader myDownloader;
public MyProgressListener(Downloader downloader) {
myDownloader = downloader;
}
public void onProgress(int n) {
// starts and waits for a thread that accesses myDownloader
}
}
Downloader downloader = new Downloader(...);
downloader.addListener(new MyListener(downloader));
downloader.run();

Is this a good design for implementing the java synchronized keyword as an object?

Just for practice I wanted to implement the java synchronized keyword as a java object.
Would you say the code below is a good design for this?
I guess AtomicReference would have a similar performance to AtomicBoolean?
Updated code after suggestions:
public class SynchronizedBlock implements Runnable{
private final Lock lock;
private final Runnable runnable;
public SynchronizedBlock(Runnable r, Lock l){
runnable = r;
lock = l;
}
public void run() {
try {
while(!lock.compareAndSet(false, true)){
Thread.sleep(100);
}
runnable.run();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
public class Lock {
private final AtomicReference<Boolean> locked = new AtomicReference<Boolean>(false);
public boolean compareAndSet(boolean expected, boolean update){
return locked.compareAndSet(expected, update);
}
public boolean isLocked(){
return locked.get();
}
public void unlock(){
locked.set(false);
}
}
#Test
public void test() {
final SynchronizedBlock sb = new SynchronizedBlock(new Runnable(){
public void run() {
x++;
System.out.println(x);
}
}, new Lock());
Runnable r1 = new Runnable(){
int c = 0;
public void run() {
while(c<10){
sb.run();
c++;
}
}
};
Runnable r2 = new Runnable(){
int c = 0;
public void run() {
while(c<10){
sb.run();
c++;
}
}
};
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
t1.start();
t2.start();
while (t1.isAlive() && t2.isAlive()){
}
assertEquals(20,x);
}
You should add a method to encapsulate the compareAndSwap, and there is no point looping for the lock to be free before attempting to obtain it. Why get in the situation where you can see the lock is free but by the time you try to take it, it is gone.
I would remove the lock method and place the unlock in a finally lock so that an Exception/Error doesn't result in a lock which never unlocks.
Also I would use an AtomicBoolean which is more natural than an AtomicReference
Firstly and most importantly, you should remove Thread.sleep(100). This will cause at least 100ms latency even in only 2-thread contention.
You can simply use AtomicBoolean instead of AtomicReference to simplify your code. Also if you're really concerned about concurrency in high-contention situation, you can modify your code to check if it's locked before doing CAS.
while (true) {
if (lock.isLocked()) continue; // or get() == true if you use AtomicBoolean
if (lock.compareAndSet(false, true))
break;
}
This is an example of TTAS(Test-Test-And-Set) locking which takes advantage of local-spinning to reduce main-memory access while looping.
See http://en.wikipedia.org/wiki/Test_and_Test-and-set

Java Threads with Observer pattern for long operations

In my application, I have two threads given ThreadA and ThreadB. ThreadA is a thread that holds and manipulates some data (the producer) and ThreadB is the corresponding consumer thread that reads from ThreadA (read-only).
I want to achieve that ThreadB informs ThreadA to update the data (which may take some time) and when the data is changed, ThreadB should get/request it from ThreadA. As long as ThreadA has not finished updating the data, ThreadB shouldn't wait but continue his work with the current (old) data he has.
Now my idea was to use the observer pattern to inform ThreadB that ThreadA has finished updating
public class ThreadA implements Runnable {
private boolean sometimesTrue = false;
private int[] someBigArray = new int[XXX];
private synchronized int[] getBigArray() {
return this.someBigArray;
}
private void fireListenerDataChanged() {
for(ThreadAListener l : listeners)
l.notify();
}
private synchronized void updateArray() {
//do some stuff on the array that takes a lot of time
}
#Override
public void run() {
while(true) {
if(sometimesTrue) {
updateArray();
}
}
}
public void doUpdate() {
this.sometimesTrue = true;
}
}
public class ThreadB implements Runnable, ThreadAListener {
private int[] bigDataToWorkOn;
private Thread threadA;
public ThreadB(ThreadA threadA) {
this.threadA = threadA;
}
#Override
public void run() {
//do my stuff with bigDataToWorkOn
if(sometimesTrue) {
threadA.doUpdate();
}
}
public void notify() {
this.bigDataToWorkOn = threadB.getBigArray();
}
}
My main goal was to avoid using some kind of BlockingQueue because then afaik ThreadB would wait with his work until ThreadA passes the data in the queue. The same problem would occur if I would call getBigArray in the while-loop in ThreadB because when ThreadA is currently working in updateArray, ThreadA would be locked and ThreadB would also wait for ThreadA to finish. So is this a proper approach?
This approach could be workable solution, except that fact, that you must mark field sometimesTrue with volatile modifier, if you don't want to have infinite loop inside your run() method of ThreadA.
Futhermore, if you don't want your ThreadA be eating 100% of single core, you have to add some delay into loop inside its run() method:
public void run() {
try {
while(true) {
if(sometimesTrue) {
updateArray();
}
Thread.sleep(100);
}
} catch (InterruptedException e) {
// ... do something with e
}
}

wait call for a particular thread

Is it possible to call wait method for another thread rather than the current thread.what I am asking is something like this :
Code:
public class a extends JApplet{
JButton start= new JButton("Start");
JButton wait= new JButton("Wait");
JButton notify = new JButton("Notify");
final Thread bthread = new Thread(new B(), "BThread");
#Override
public void init(){
//start
this.getContentPane().setLayout(new FlowLayout());
start.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Started");
}
});
this.getContentPane().add(start);
//wait
wait.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Waited");
synchronized(bthread) //something like this
{
try {
bthread.wait(); //is it possible instead of the current thread the bthread get invoke
} catch (Exception ex) {
Logger.getLogger(a.class.getName()).log(Level.SEVERE, null, ex);
}}
}
});
this.getContentPane().add(wait);
//notify
notify.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Notified");
synchronized(a.this){
a.this.notify();
}}
});
this.getContentPane().add(notify);
}
class B implements Runnable
{
int i=0;
#Override
public void run() {
while(i<10){
System.out.println(" i = "+i);
// i++;
}
}
}
}
Is it possible that when wait button is clicked the bthread go into wait state?
do you want bthread to actually pause its execution, whatever it is doing? There's no way to do that, AFAIK. You may however set bthread polling on some shared stateful synchronization object (a CountDownLatch or a Semaphore for instance, look into the java.util.concurrent package), so that you alter the status of the object to set bthread waiting.
No. You can't suspend a thread like that.
But you can implement a wait method in the B class:
class B implements Runnable
{
private boolean wait = false;
public void pause() {
wait = true;
}
int i=0;
#Override
public void run() {
while(i<10){
if (wait) {
wait();
}
System.out.println(" i = "+i);
// i++;
}
}
}
I dont think so.
Thread B can check some variable, for example boolean pause; If its true it can wait. It needs to be volatile or needs synchronization and something to wake it up is needed, but that depends on what you want it to do.
But if thread B is doing some long operation, it can be running long time before it checks whether it should wait.
No, you can only control the current thread, if you wait on another thread you actually call wait() using that object (the thread you are referring to) as a monitor. So you either have to time out, or someone call interrupt on that object to make your current thread start again.
You have to build that logic into your program, causing it to wait after a variable or message be flagged. Another way would be using locks or semaphores.
You could also call interrupt on that thread if you want it to stop, but that logic must also be built into your program, as it might just throw an InterruptedException if the thread is doing IO.

Categories