Thread Waits for a lock when it shouldn't be - java

i am practicing on java threads, and i am confused with Locking mechanism,
What i am trying to achieve is when a thread is taking much time to execute a block of code whose lock it has acquired, the other thread should just not wait and go for the else condition,
this is my code as follows
import java.util.concurrent.locks.*;
import java.util.concurrent.*;
class MySharedData{
private volatile boolean bFlag;
private int counter=1;
public void abuseIt() throws Exception{
while(!bFlag){
System.out.println(" THREAD "+Thread.currentThread().getName()+" WITH COUNTER "+counter);
counter++;
Thread.sleep(1000);
if(counter > 20){
bFlag=true;
}
}
}
}
class RequesterThree implements Runnable{
private Lock lock;
RequesterThree(){
lock = new ReentrantLock();
}
#Override
public void run(){
MySharedData myShared = null;
try{
myShared = new MySharedData();
if(lock.tryLock(250,TimeUnit.MILLISECONDS)){
myShared.abuseIt();
}else{
System.out.println(Thread.currentThread().getName()+": SHARED DATA IS NON-ACCESSIBLE !!!!");
}
}catch(Exception e){
System.out.println(e);
}finally{
lock.unlock();
}
}
}
public class Ex03{
public static void main(String [] args){
Thread[] requests = new Thread[]{
new Thread(new RequesterThree(),"MICHEAL"),
new Thread(new RequesterThree(),"SHAWN"),
new Thread(new RequesterThree(),"JOHN"),
new Thread(new RequesterThree(),"TRON"),
new Thread(new RequesterThree(),"FINCH")
};
for(int x=0; x < requests.length; x++){
requests[x].start();
}
}
}
But here all of the five threads wait for the lock, and not a single thread prints the SOP in the else condition,
What i am expecting is,
When Thread T1 is started, it acquires the lock, and execute the abuseIt() method, there it sleeps for 1 sec,
Now thread T2 should wait for the lock to get free for only 250 milisec, but T1 is any how waiting for 1 sec, so T2 should execute the else condition in the run method,
How can i achieve this,

In your code, each RequesterThree object has a separate lock, so there is no synchronization across them.
Additionally, each thread calls myShared.abuseIt() on its own dedicated instance of MySharedData.
To fix:
private static final Lock lock = new ReentrantLock();
private static final MySharedData myShared = new MySharedData();
Also, remove the constructor and the change the run() method:
#Override
public void run(){
try{
if(lock.tryLock(250,TimeUnit.MILLISECONDS)){
Finally, your code can call unlock() even if tryLock() hasn't succeeded. This needs to be fixed.

Make your lock field final static
...
class RequesterThree implements Runnable{
private static final Lock lock = new ReentrantLock();
RequesterThree(){
}
...

Related

Java Multi threading semaphore

The counter variable does not accurately reflect how many times increment
method is invoked. Why not, and how can it be fixed? (You do not have to write code,
just use English.)
Original:
import java.util.*;
import java.lang.*;
import java.io.*;
class Foopadoop
{
public static int counter = 0;
public static void main(String[] args) throws Exception {
Runnable r = new Runnable() {
public void run() {
while(true){
counter++;
}
}
};
Thread t1 = new Thread(r);
Thread t2 = new Thread(r);
t1.start();
t2.start();
}
}
Mine, I added a semaphore but I'm not sure if I'm doing it right or am I suppose to use a lock.
import java.util.*;
import java.lang.*;
import java.io.*;
import java.util.concurrent.Semaphore;
class Foopadoop
{
public static int counter = 0;
Semaphore lock = new Semaphore(0);
public static void main(String[] args) throws Exception {
Runnable r = new Runnable() {
try{public void run() {
while(true){
counter++;
lock.acquire();
}
}
}finally{
lock.release();
}
};
Thread t1 = new Thread(r);
Thread t2 = new Thread(r);
t1.start();
t2.start();
}
}
That's not how you use a Semaphore.
You acquire it before you access the shared resource, and release it after:
while (true) {
try {
lock.acquire();
counter++;
} finally {
lock.release();
}
}
Since you acquire first, you will also need at least 1 permit, otherwise there is nothing to acquire:
static Semaphore lock = new Semaphore(1);
A synchronized block is easier than a Semaphore:
while (true) {
synchronized (Foopadoop.class) {
counter++;
}
}
or an AtomicInteger:
static AtomicInteger counter = new AtomicInteger();
// ...
while (true) {
counter.getAndIncrement();
}
Also you can add Thread.sleep(ms) inside the while loop, so that it will pause the current thread for some time, & start executing other threads. Otherwise the current thread might run in a selfish manner (selfish thread).

synchronization : Threads execute two critical sections in same order

I have the following kind of code:
synchronized block1 {
//only one thread in the block
}
{lot of code where synchronization not necessary}
synchronized block2 {
//only one thread in the block.
//All the threads that executed block1 before this thread should have already executed this block.
}
Each thread first executes block1, non synchronized block, and block2 in that same order.
If thread T1 executes block1 before thread T2, then T1 should execute block2 before T2. There are more than two threads.
Is there a way to achieve this in java?
As I understand Critical Section #2 MUST be executed in the same order as Critical Section #1
If thread T1 executes block1 before thread T2, then T1 should execute block2 before T2. There are more than two threads.
Then a Queue might be used to ensure the order of execution.
private Object lock = new Object();
private Queue<Thread> threadQueue = new ArrayDeque<>();
// https://stackoverflow.com/questions/32353283/synchronization-threads-execute-two-critical-sections-in-same-order
public void executeCriticalSectionsInOrder() throws InterruptedException {
// Critical Section #1
synchronized (lock){
// synchronized code #1
// Add self to queue
threadQueue.add(Thread.currentThread());
}
// {lot of code where synchronization not necessary}
// Critical Section #2
synchronized (lock) {
//All the threads that executed block1 before this thread should have already executed this block.
// Wait turn
Thread t = threadQueue.element(); // Do not remove until it is self
while (t != Thread.currentThread()) {
lock.wait();
// After sleep try again
t = threadQueue.element();
}
// Verified own turn. Update status
threadQueue.remove();
// synchronized code #2
lock.notifyAll(); // Awake any waiting thread after exiting section.
}
However If one thread dies/exits without removing itself from the queue, then following threads will be blocked indefinetely. Maybe add a finally block to do the housekeeping?
Note: In Nicholas Robinson's answer a position order was suggested instead of a queue, which seems slightly more efficient.
This basically creates a queue that threads will wait in until their number comes up. [UPDATED]
private AtomicInteger place = new AtomicInteger(0);
private AtomicInteger currentPlaceInQueue = new AtomicInteger(0);
private ReentrantLock lock = new ReentrantLock();
private Condition notNext = lock.newCondition();
public void method() {
ThreadLocal position = new ThreadLocal();
synchronized(this) {
//Your code
position.set(place.getAndIncrement());
}
// More code
lock.lock();
while ((int) currentPlaceInQueue.get() != position.get()) {
notNext.await();
}
// More code
lock.unlock();
currentPlaceInQueue.getAndIncrement();
notNext.notifyAll();
}
The synchronized blocks in your example are a red herring. Your problem is, you have N threads, and you have two blocks of code, and you want to make sure that none of the threads enters the second block until all of them have finished the first block.
You use a CyclicBarrier for that. http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CyclicBarrier.html
You should be able to use a Lock which you take before calling block1 and release after calling block2.
static Lock lock = new ReentrantLock();
Random random = new Random();
public void block1() throws InterruptedException {
System.out.println("Enter block 1");
Thread.sleep(random.nextInt(500));
System.out.println("Leave block 1");
}
public void block2() throws InterruptedException {
System.out.println("Enter block 2");
Thread.sleep(random.nextInt(500));
System.out.println("Leave block 2");
}
private class BlockTester implements Runnable {
long start = System.currentTimeMillis();
#Override
public void run() {
while (System.currentTimeMillis() < start + 10000) {
lock.lock();
try {
System.out.println("Thread: " + Thread.currentThread().getName());
block1();
block2();
} catch (InterruptedException ex) {
System.out.println("Interrupted");
} finally {
lock.unlock();
}
}
}
}
public void test() throws InterruptedException {
Thread[] blockTesters = {
new Thread(new BlockTester()),
new Thread(new BlockTester()),
new Thread(new BlockTester()),
new Thread(new BlockTester()),
new Thread(new BlockTester())
};
for (Thread t : blockTesters) {
t.start();
}
for (Thread t : blockTesters) {
t.join();
}
}

synchronized increment an int value

Why this program doesn`t display 2000 at every execution? I know that I can use AtomicInteger, but I am curious.
class Increment extends Thread{
static Integer i=new Integer(0);
public void run(){
for(int j=1;j<=1000;j++){
synchronized (i) {
i++;
}
}
}
}
public class Puzzle {
public static void main(String args[]) {
Thread t1=new Increment();
Thread t2=new Increment();
t1.start();
t2.start();
try {
t1.join();
t2.join();
}catch (InterruptedException r){}
System.out.println(Increment.i);
}
}
You synchronize on a mutable variable i. This variable changes its value each time, therefore each time you acquire a lock on another object. Each thread thus acquires a non-contended lock and can proceed simultaneously, as if no synchronization was in place.
Lesson: use a dedicated private static final Object lock = new Object() as a lock.

Synchronization with threads

I have a two part question...
I have a class with a function in it that can only be accessed by any one thread at a given time. Making this a synchronized function or a synchronized block still allows for multiple threads since different threads are accessing it within the class. How can I make sure only one thread accesses this code? (See code example below)
With the synchronized function, the calls to the function are queued up. Is there any way to only allow the last call to the function to access the code? So if I have Thread1 currently accessing my function, then Thread2 and Thread3 try to access it (in that order) only Thread3 will be given access once Thread1 is complete.
public void doATask() {
// I create a new thread so the interface is not blocked
new Thread(new Runnable() {
#Override
public void run() {
doBackgroundTask();
}
}).start();
}
private void doBackgroundTask(MyObject obj) {
// perform long task here that is only being run by one thread
// and also only accepts the last queued thread
}
Thanks for any help!
If the second thread in your example can just return, you could use a combination of a lock and keeping track of the last thread executing the method. It could look like this:
private volatile Thread lastThread;
private final ReentrantLock lock = new ReentrantLock();
private void doBackgroundTask(Object obj) throws InterruptedException {
Thread currentThread = Thread.currentThread();
lastThread = currentThread;
try {
// wait until lock available
lock.lockInterruptibly();
// if a thread has arrived in the meantime, exit and release the lock
if (lastThread != currentThread) return;
// otherwise
// perform long task here that is only being run by one thread
// and also only accepts the last queued thread
} finally {
lock.unlock();
}
}
Full working test with additional logging that shows the thread interleaving and that T2 exits without doing nothing:
class Test {
private volatile Thread lastThread;
private final ReentrantLock lock = new ReentrantLock();
public static void main(String[] args) throws Exception {
final Test instance = new Test();
Runnable r = new Runnable() {
#Override
public void run() {
try {
instance.doBackgroundTask(null);
} catch (InterruptedException ignore) {}
}
};
Thread t1 = new Thread(r, "T1");
Thread t2 = new Thread(r, "T2");
Thread t3 = new Thread(r, "T3");
t1.start();
Thread.sleep(100);
t2.start();
Thread.sleep(100);
t3.start();
}
private void doBackgroundTask(Object obj) throws InterruptedException {
Thread currentThread = Thread.currentThread();
System.out.println("[" + currentThread.getName() + "] entering");
lastThread = currentThread;
try {
// wait until lock available
lock.lockInterruptibly();
// if a thread has arrived in the meantime, exit and release the lock
if (lastThread != currentThread) return;
// otherwise
// perform long task here that is only being run by one thread
// and also only accepts the last queued thread
System.out.println("[" + currentThread.getName() + "] Thinking deeply");
Thread.sleep(1000);
System.out.println("[" + currentThread.getName() + "] I'm done");
} finally {
lock.unlock();
System.out.println("[" + currentThread.getName() + "] exiting");
}
}
}
Output:
[T1] entering
[T1] Thinking deeply
[T2] entering
[T3] entering
[T1] I'm done
[T1] exiting
[T2] exiting
[T3] Thinking deeply
[T3] I'm done
[T3] exiting
What you want is probably a worker thread that waits for a signal to do some work. doATask() simply sends a signal to trigger the work. Accumulative signals are equivalent to one signal.
final Object lock = new Object();
MyObject param = null;
public void doATask(arg)
synchronized(lock)
param=arg;
lock.notify();
MyObject awaitTask()
synchronized(lock)
while(param==null)
lock.wait();
tmp=param;
param=null;
return tmp;
// worker thread
public void run()
while(true)
arg = awaitTask();
doBackgroundTask(arg);

How to wait from thread1 until notified by thread2

I am new to multi-threading and While I am reading about multi threading, thought of writing this fancy multi-threading code to do the following.
My counter class is as follows.
class Counter {
private int c = 0;
public void increment() {
System.out.println("increment value: "+c);
c++;
}
public void decrement() {
c--;
System.out.println("decrement value: "+c);
}
public int value() {
return c;
}
}
This Counter object is shared between two threads.
Once threads are started, I need to do the following.
I want Thread2 to wait until the Thread1 increments the count of the Counter object by 1.
Once this is done, Then Thread 1 informs thread2 and then Thread1 starts waiting for thread2 to decrement value by 1.
Then thread2 starts and decrements value by 1 and informs thread1 again and then thread2 start waiting for thread1. Repeat this process for few times.
How can I achieve this. Many thanks in advance.
I have done the following.
public class ConcurrencyExample {
private static Counter counter;
private static DecrementCount t1;
private static IncrementCount t2;
public static void main(String[] args) {
Counter counter = new Counter();
Thread t1 = new Thread(new IncrementCount(counter));
t1.start();
Thread t2 = new Thread(new DecrementCount(counter));
t2.start();
}
}
public class DecrementCount implements Runnable {
private static Counter counter;
public DecrementCount(Counter counter) {
this.counter = counter;
}
#Override
public void run() {
for (int i = 0; i < 1000; i++) {
counter.decrement();
System.out.println("decreamented");
}
}
}
public class IncrementCount implements Runnable {
private static Counter counter;
public IncrementCount(Counter counter) {
this.counter = counter;
}
#Override
public void run() {
for (int i = 0; i < 1000; i++) {
counter.increment();
System.out.println("Incremented");
}
}
}
Check out Semaphore. You'll need two, one for each thread: incSemaphore and decSemaphore. In DecrementCount do:
for (int i = 0; i < 1000; i++) {
decSemaphore.acquire();
counter.decrement();
System.out.println("decreamented");
incSemaphore.release();
}
Implement IncrementCount symmetrically. Initial value of incSemaphore should be 1 and 0 for decSemaphore.
BTW your Counter requires synchronization as well (see synchronized keyword and AtomicInteger).
Synchronizers enable threads to wait for one another. See CountDownLatch and Semaphore.
See Synchronizers section in the java.util.concurrent package
- First your increment() and decrement() must be using synchronized keyword to avoid the Race Condition See this Brian's Rule
When we write a variable which has just been read by another thread, or reading a variable which is just lately written by another thread, must be using Synchronization. And those atomic statements/Methods accessing the fields' data must be also synchronized.
- Its the JVM Thread Scheduler that has control Which thread will enter the Running State, how long its gonna stay there, and where it will go after its work has been done.
- One Cannot be sure of which thread will run first.....
- You can also use SingleThreadExecutor from java.util.concurrent, this completes one task before moving onto the second.
Use Condition with boolean flag.
final Lock lock = new ReentrantLock();
final Condition incremented= lock.newCondition();
final Condition decremented= lock.newCondition();
Change your Counter to below
Explanation :
We have used two conditions one is incremented and one is decremented. based on boolean flag we check whether we have to wait on one condition or not.
class Counter {
private int c = 0;
boolean increment = false;
final Lock lock = new ReentrantLock();
final Condition incremented = lock.newCondition();
final Condition decremented = lock.newCondition();
public void increment() throws InterruptedException {
Lock lock = this.lock;
lock.lock();
try {
while(increment)
decremented.await();
increment = true;
c++;
System.out.println("increment value: " + c);
incremented.signal();
} finally {
lock.unlock();
}
}
public void decrement() throws InterruptedException {
Lock lock = this.lock;
lock.lock();
try {
while (!increment)
incremented.await();
c--;
System.out.println("decrement value: " + c);
increment = false;
decremented.signal();
} finally {
lock.unlock();
}
}
public int value() {
Lock lock = this.lock;
lock.lock();
try {
return c;
} finally {
lock.unlock();
}
}
}

Categories