Each Thread using unique ID and releasing it for reuse - java

Below is the code in which in the run method, I am always trying to get unique id from the availableExistingIds and releasing it at the same moment by making a linked list order, but in certain cases I found out that, I am getting NoSuchElementException and id is zero few times which I think should not be the case anytime.
class IdPool {
private final LinkedList<Integer> availableExistingIds = new LinkedList<Integer>();
public IdPool() {
for (int i = 1; i <= 1000; i++) {
availableExistingIds.add(i);
}
}
public synchronized Integer getExistingId() {
return availableExistingIds.removeFirst();
}
public synchronized void releaseExistingId(Integer id) {
availableExistingIds.add(id);
}
}
class ThreadNewTask implements Runnable {
private IdPool idPool;
private int id;
public ThreadNewTask(IdPool idPool) {
this.idPool = idPool;
}
public void run() {
try {
id = idPool.getExistingId();
//Anything wrong here?
if(id==0) {
System.out.println("Found Zero");
}
someMethod(id);
} catch (Exception e) {
System.out.println(e);
} finally {
idPool.releaseExistingId(id);
}
}
// This method needs to be synchronized or not?
private synchronized void someMethod(Integer id) {
System.out.println("Task: " +id);
// and do other calcuations whatever you need to do in your program
}
}
Problem Statement:-
How can I avoid this zero id case here in my code? One scenario under which I can get id = 0 is when the id pool is exhausted (empty). When that happens, the line:
id = idPool.getExistingId();
will fail with a NoSuchElementException. In this case, the finally block will run:
idPool.releaseExistingId(id);
But id will still have its default value of 0 since the first line failed. So I end up "releasing" 0 and adding it back to the id pool even though it was never in the pool to start with. Then a later task could take 0 legitimately. And that's what I don't need. Can anyone suggest me how to overcome this scenario in my code? I always want id should be in the range of 1 to 1000.

why don't you modify your code so that instead of crashing when there are no available ids, it waits for one to become available?
Otherwise, every time you have too much threads working at once, the pool is going to be exhausted, and you are going to have to deal with a lot of failing threads. Also the synchronization work is taken care of for you automatically.
EDIT: here is the modified code
class ThreadNewTask implements Runnable {
private BlockingQueue<Integer> pool;
private int id;
public ThreadNewTask(BlockingQueue<Integer> pool) {
this.pool = pool;
}
public void run() {
try {
id = pool.take();
someMethod(id);
} catch (Exception e) {
System.out.println(e);
} finally {
pool.offer(id);
}
}
private void someMethod(Integer id) {
System.out.println("Task: " +id);
// and do other calcuations whatever you need to do in your program
}
}
And then you initialize the pool with something like this:
LinkedList<Integer> availableExistingIds = new LinkedList<Integer>();
for (int i = 1; i <= 1000; i++) {
availableExistingIds.add(i);
}
BlockingQueue<Integer> pool = new ArrayBlockingQueue<Integer>(1000, false, availableExistingIds);

Related

How to start new Thread to continue work when Sleep is called within a Thread in Java

I am creating a Thread calling a custom compare method within a class - FastestComparator.java
The Thread Class:
public class FastestComparatorThread extends Thread {
private int valueToFind;
private List<CustomNumberEntity> list;
private FastestComparator fastComparator = new FastestComparator();
private int result = 1;
public FastestComparatorThread(int valueToFind, List<CustomNumberEntity> list) {
this.valueToFind = valueToFind;
this.list = list;
}
public int getResult() {
return result;
}
#Override
public void run() {
for (CustomNumberEntity customNumberEntity : list) {
try {
synchronized(fastComparator) {
result = fastComparator.compare(valueToFind, customNumberEntity);
System.out.println(result);
}
} catch (NumberFormatException e) {}
}
}
}
The Compare Method has a Sleep function within it:
public int compare(int firstValue, CustomNumberEntity secondValue){
Random random = new Random();
int mSeconds = (random.nextInt(6)+5)*1000; //milliseconds
int secondValueAsNumber = Integer.parseInt(secondValue.getNumber());
try {
Thread.sleep(mSeconds);
} catch (InterruptedException e) {
//error while sleeping. Do nothing.
}
return firstValue-secondValueAsNumber;
}
Currently, after starting the Thread, I am calling the interrupt() method, while the Thread isAlive() essentially to avoid the sleep after starting the Thread
FastestComparatorThread fastestComparatorThread = new FastestComparatorThread(valueToFind, list);
fastestComparatorThread.start();
while(fastestComparatorThread.isAlive()) {
fastestComparatorThread.interrupt();
if (fastestComparatorThread.getResult() == 0) {
return true;
}
}
Is there a way of kicking off a new thread that continues the work when the first one sleeps instead of continuously interrupting the one Thread?
Is there a way of kicking off a new thread that continues the work when the first one sleeps...?
No. The Thread.sleep(nnnn) call does nothing. It does nothing for approximately nnnn milliseconds (but never less than nnnn milliseconds), and then it returns. There is no provision in Java for one thread to be automatically notified when some other thread calls sleep().

java CyclicBarrier not broken with reset

I am trying to test BrokenBarrierException by resetting the cyclicbarrier in the middle of starting (awaiting) few parties (threads), please find the below sample code for the same.
User class:
public class User implements Runnable {
private final String name;
private final CyclicBarrier cb;
public User(String name, CyclicBarrier cb) {
this.name = name;
this.cb = cb;
}
#Override
public void run() {
System.out.println(name+" user started !!!! ");
try {
cb.await();
} catch (InterruptedException | BrokenBarrierException e) {
System.out.println(e);
e.printStackTrace();
}
}
}
CyclicBarrierTest class:
public class CyclicBarrierTest {
public static void main(String[] args) {
CyclicBarrier barrier = new CyclicBarrier(5);
User user1 = new User("USER1", barrier);
new Thread(user1).start();
User user2 = new User("USER2", barrier);
new Thread(user2).start();
//Expected users are 5, but only 2 user threads started so far
// and resetting below which should throw barrier broken exception
barrier.reset();
if(barrier.isBroken()) {
System.out.println("Barrier broken ");
}
}
}
So, after running the main() above, I could get any exceptions and also "Barrier broken" also not printed. The threads are simply waiting.
I have referred the CyclicBarrier API below link:
https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CyclicBarrier.html
public void reset():
Resets the barrier to its initial state. If any
parties are currently waiting at the barrier, they will return with a
BrokenBarrierException.
But my above code doesn't seems to work according to the API description, so what is the problem with my above code and why it is NOT throwing BrokenBarrierException ?
Could you please help ?
If you want exception thrown , you have to make sure barrier.reset(); executes after cb.await(); , but here System.out.println(name+" user started !!!! "); is a very costly statement which makes barrier.reset(); executes too early , you can add a sleep statement before barrier.reset(); , say Thread.sleep(100);.
Doc of isBroken :
true if one or more parties broke out of this barrier due to interruption or timeout since construction or the last reset, or a barrier action failed due to an exception; false otherwise.
If you want it as broken , you can do something to the parties . You need remove reset to make threads awaiting .
public class User implements Runnable {
private final String name;
private final CyclicBarrier cb;
public User(String name, CyclicBarrier cb) {
this.name = name;
this.cb = cb;
}
#Override
public void run() {
System.out.println(name+" user started !!!! ");
try {
cb.await(1,TimeUnit.SECONDS);
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
} catch (TimeoutException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(name+" user ended !!!! ");
}
}
public class CyclicBarrierTest {
public static void main(String[] args) throws Exception {
CyclicBarrier barrier = new CyclicBarrier(5);
User user1 = new User("USER1", barrier);
new Thread(user1).start();
User user2 = new User("USER2", barrier);
new Thread(user2).start();
//Expected users are 5, but only 2 user threads started so far
// and resetting below which should throw barrier broken exception
Thread.sleep(100);
// barrier.reset();
Thread.sleep(1100);
if(barrier.isBroken()) {
System.out.println("Barrier broken ");
}
}
}
Short answer:
On reset the barrier loses the information of previous BrokenBarrierException(s). So any call to isBroken after reset will return false.
The javadoc specify this, although, not very clearly:
isBroken return: true if one or more parties broke out of this barrier due to interruption or timeout since construction or the last reset, or a barrier action failed due to an exception; false otherwise.
Long answer:
You can see more clearly what happens if you look at source code of reset and isBroken:
public void reset() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
breakBarrier(); // break the current generation
nextGeneration(); // start a new generation
} finally {
lock.unlock();
}
}
private void breakBarrier() {
generation.broken = true;
count = parties;
trip.signalAll();
}
private void nextGeneration() {
// signal completion of last generation
trip.signalAll();
// set up next generation
count = parties;
generation = new Generation();
}
private static class Generation {
boolean broken = false;
}
public boolean isBroken() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
return generation.broken;
} finally {
lock.unlock();
}
}
You can see that the reference generation.broken holds the information about a broken barrier. But this is reinitialized to false on reset.

All threads get locked in wait() state [duplicate]

This question already has answers here:
Notify not getting the thread out of wait state
(3 answers)
Closed 7 years ago.
Basically I have to create 3 classes (2 threaded).
First one holds some cargo (has a minimum capacity (0) and a maximum (200))
Second one supplies the cargo every 500ms.
Third one takes away from cargo every 500ms.
Main program has one cargo class(1), 2 supplier classes(2) and 2 substraction classes(3). Problem I'm having is that one by one, they're falling into a wait(); state and never get out. Eventually all of them get stucked in the wait() state, with the program running, but without them actually doing anything.
First class:
public class Storage {
private int maxCapacity;
private int currentCapacity;
public Storage( int currentCapacity, int maxCapacity ) {
this.currentCapacity = currentCapacity;
this.maxCapacity = maxCapacity;
}
public int getCapacity(){ return this.currentCapacity; }
public void increase( int q ) {
this.currentCapacity += q;
System.out.println("increase" + q + ". Total: " + currentCapacity);
}
public int getMax() { return this.maxCapacity; }
public void decrease( int q ) {
this.currentCapacity -= q;
System.out.println("decrease - " + q + ". Total: " + currentCapacity);
}
}
2nd class (supplier):
public class Supplier implements Runnable {
private int capacity;
private Storage storage;
private volatile boolean run;
public Supplier( int capacity, Storage storage ) {
this.capacity = capacity;
this.storage = storage;
this.run = true;
}
public void kiss_kill() { run = !run; }
public synchronized void add() {
while(storage.getCapacity() + capacity > storage.getMax()) {
try {
System.out.println("wait - supplier");
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
storage.increase(capacity);
notifyAll();
}
public void run() {
synchronized (this) {
while(run) {
add();
Thread.yield(); //would be wait(500), but this just speeds it up
}
}
}
}
3rd class (taker/demander):
public class Taker implements Runnable {
private int capacity;
private Storage storage;
private volatile boolean run;
public Taker( int capacity, Storage storage ) {
this.capacity = capacity;
this.storage = storage;
this.run = true;
}
public void kiss_kill() { run = !run; }
public synchronized void take() {
while(storage.getCapacity() - capacity < 0) {
try {
System.out.println("wait - taker");
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
storage.decrease(capacity);
notifyAll();
}
public void run() {
synchronized (this) {
while(run) {
take();
Thread.yield(); //again, wait(500) should be instead
}
}
}
}
Main is something like this:
public class Main{
public static void main(String... args) {
Storage sk = new Storage(100, 200);
Supplier[] s = { new Supplier(10, sk), new Supplier(15, sk) };
Taker[] p = { new Taker(15, sk), new Taker(20, sk) };
Thread t[] = {
new Thread(s[0]),
new Thread(s[1]),
new Thread(p[0]),
new Thread(p[1]) };
for(Thread th : t) th.start();
try {
Thread.sleep(60000); //program should last for 60s.
} catch (InterruptedException e) {
e.printStackTrace();
}
s[0].kiss_kill(); s[1].kiss_kill(); p[0].kiss_kill(); p[1].kiss_kill();
}
}
Why doesn't notifyAll() release the wait() state of other object? What could I do to fix this?
Sorry, I know it's a long example, I hate posting too many classes like this. Thanks for reading!
I translated the code, so if you spot anything that you're unsure about that I've missed, please tell me and I'll fix it right away!
Doing concurrency is easy:
Anyone can slap synchronized on methods and synchronized () {} around blocks of code. It does not mean it is correct. And then they can continue to slap synchronized on everything until it works until it doesn't.
Doing concurrency correctly is Hard:
You should lock on the data that needs to be consistent not the methods making the changes. And you have to use the same lock instance for everything.
In this case that is the currentCapacity in Storage. That is the only thing that is shared and the only thing that needs to be consistent.
What you are doing now is having the classes lock on instances of themselves which means nothing shared is being protected because there is no shared lock.
Think about it, if you are not locking on the same exact instance which must be final of an object then what are you protecting?
Also what about code that has access to the object that needs to be consistent and does not request a lock on it. Well it just does what it wants. synchronized() {} in calling classes is not how you protect shared data from external manipulation.
Thread safe objects are NOT about the synchronized keyword:
Read up on the java.util.concurrent package it has all the things you need already. Use the correct data structure for your use case.
In this particular case if you use AtomicInteger for your counter, you do not need any error prone manual locking, no need for synchronized anywhere, it is already thread safe.
Immutable Data:
If you work with immutable data exclusively you do not need any of this silly locking semantics that are extremely error prone for even those that understand it and even more so for those that think they understand it.
Here is a working idiomatic example:
This is a good chance to learn what non-deterministic means and how to use the step debugger in your IDE to debug concurrent programs.
Q33700412.java
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
import com.vertigrated.FormattedRuntimeException;
public class Q33700412
{
public static void main(final String[] args)
{
final Storage s = new Storage(100);
final int ap = Runtime.getRuntime().availableProcessors();
final ExecutorService es = Executors.newFixedThreadPool(ap);
for (int i = 0; i < ap; i++)
{
es.execute(new Runnable()
{
final Random r = new Random();
#Override
public void run()
{
while (true)
{
/* this if/else block is NOT thread safe, I did this on purpose
the state can change between s.remainingCapacity() and
the call to s.increase/s.decrease.
This is ok, because the Storage object is internally consistent.
This thread might fail if this happens, this is the educational part.
*/
if (s.remainingCapacity() > 0)
{
if (r.nextBoolean()) { s.increase(r.nextInt(10)); }
else { s.decrease(10); }
System.out.format("Current Capacity is %d", s.getCurrentCapacity());
System.out.println();
}
else
{
System.out.format("Max Capacity %d Reached", s.getMaxCapacity());
System.out.println();
}
try { Thread.sleep(r.nextInt(5000)); }
catch (InterruptedException e) { throw new RuntimeException(e); }
}
}
});
}
es.shutdown();
try
{
Thread.sleep(TimeUnit.MINUTES.toMillis(1));
es.shutdown();
}
catch (InterruptedException e) { System.out.println("Done!"); }
}
public static final class Storage
{
/* AtomicInteger is used so that it can be mutable and final at the same time */
private final AtomicInteger currentCapacity;
private final int maxCapacity;
public Storage(final int maxCapacity) { this(0, maxCapacity); }
public Storage(final int currentCapacity, final int maxCapacity)
{
this.currentCapacity = new AtomicInteger(currentCapacity);
this.maxCapacity = maxCapacity;
}
public int remainingCapacity() { return this.maxCapacity - this.currentCapacity.get(); }
public int getCurrentCapacity() { return this.currentCapacity.get(); }
public void increase(final int q)
{
synchronized (this.currentCapacity)
{
if (this.currentCapacity.get() < this.maxCapacity)
{
this.currentCapacity.addAndGet(q);
}
else
{
throw new FormattedRuntimeException("Max Capacity %d Exceeded!", this.maxCapacity);
}
}
}
public int getMaxCapacity() { return this.maxCapacity; }
public void decrease(final int q)
{
synchronized (this.currentCapacity)
{
if (this.currentCapacity.get() - q >= 0)
{
this.currentCapacity.addAndGet(q * -1);
}
else
{
this.currentCapacity.set(0);
}
}
}
}
}
Notes:
Limit the scope of synchronized blocks to the minimum they need to protect and lock on the object that needs to stay consistent.
The lock object must be marked final or the reference can change and you will be locking on different instances.
The more final the more correct your programs are likely to be the first time.
Jarrod Roberson gave you the "how" half of the answer. Here's the other half--the "why".
Your Supplier object's add() method waits on itself (i.e., on the supplier object), and it notifies itself.
Your Taker object's take() method waits on its self (i.e., on the taker object), and it notifies its self.
The supplier never notifies the taker, and taker never notifies the supplier.
You should do all of your synchronization on the shared object (i.e., on the Storage object.
So I should convert storage into a thread?
No, you don't want Storage to be a thread, you want it to be the lock. Instead of having your Supplier objects and your Taker objects synchronize on themselves, they should all synchronize on the shared Storage object.
E.g., do this:
public void take() {
synchronized(storage) {
while(...) {
try {
storage.wait();
} catch ...
}
...
storage.notifyAll();
}
}
Instead of this:
public synchronized void take() {
while(...) {
try {
wait();
} catch ...
}
...
notifyAll();
}
And do the same for all of your other synchronized methods.

Java monitor returns wrong value from private variable

I'm implementing a barrier in java that when accesed by a thread it creates a new object, with a value from the parameter, stored in a private variable to later be returned. Then, when another thread calls the barrier it completes the former object with this other parameter. The first pair goes on well, the rest receive the same object the first pair created.
private Barrier aBarrier;
private boolean first = true;
public synchronized Barrier pairUp(int id){
try{
if(first){
first = false;
aBarrier = new Barrier(); aBarrier.setFirst(id);
wait();
}
else{
first = true;
aBarrier.setLast(id);
notify();
}
}
catch(InterruptedException e){System.out.printf("ERROR");}
return aBarrier;
}
And this would be what every process calling the method above looks like.
private int id = ID OF THE PROCESS, 14 RUN CONCURRENTLY SO FROM 0 TO 13 (this is set in the constructor method);
public void run() {
while(true){
myBarrier = pairUp(id);
myBarrier.goThrough();
//Do stuff that doesn't matter here
// ....
}
}
A Barrier object contains two integers and a method to do more stuff later.
If I reset the private variable aBarrier to null before or after the calls it always gives null back.
I feel like I'm missing some stupid thing here.
If a process calls the method pairUp() after the first pair it will get the first Barrier.
I use this to diferentiate which process came first in the pairUp method.
Thanks beforehand!
A Barrier object contains two integers and a method to do more stuff later. If I reset the private variable aBarrier to null before or after the calls it always gives null back. I feel like I'm missing some stupid thing here.
I think the problem is that you are returning aBarrier after the wait/notify calls but it might have been changed by subsequent threads. Storing it in a local variable so it won't be changed is key.
You might also have had multiple versions of the wrapping object so your synchronized statement is synchronizing on a different object?
Couple things to note in the code below:
The System.out.println(...) changes the synchronization. Need to be careful here.
I used the aBarrier being null or not to replace the first boolean.
Code:
public class Foo implements Runnable {
private static int NUM_THREADS = 14;
private static final AtomicInteger idCounter = new AtomicInteger();
private static final ExecutorService threadPool = Executors.newFixedThreadPool(NUM_THREADS);
private static Barrier aBarrier = null;
public static void main(String[] args) {
// only 1 Foo object
Foo foo = new Foo();
for (int i = 0; i < NUM_THREADS; i++) {
threadPool.execute(foo);
}
}
public synchronized Barrier pairUp(int id) {
Barrier barrier = aBarrier;
try {
if (barrier == null) {
barrier = new Barrier();
barrier.first = id;
aBarrier = barrier;
wait();
} else {
barrier.last = id;
aBarrier = null;
notify();
}
} catch (InterruptedException e) {
// always a good pattern
Thread.currentThread().interrupt();
e.printStackTrace();
barrier = null;
}
// return local barrier because aBarrier might have changed
return barrier;
}
#Override
public void run() {
int id = idCounter.incrementAndGet();
while (true) {
Barrier myBarrier = pairUp(id);
// System.out.println is synchronized so it may move the bug
System.out.println(id + ": " + myBarrier.first + " and " + myBarrier.last);
}
}
private static class Barrier {
int first;
int last;
}
}

How to solve this thread blocking issue

I'm testing a Java multi-threading sample code but the thread started in the for loop of qB.start() is blocked because it's waiting for entry of qB monitor. What is the cause of this blockage?
Thank you.
import java.util.*;
class QA {
public synchronized void open() throws Exception {
Thread o = new Thread() {
public void run() {
QB qB = new QB();
qB.start();
}
};
o.start();
}
public static void main(String args[]) throws Exception {
new QA().open();
}
public class QB {
private boolean shutdown;
private Vector<Thread> tList;
private final Object waitingLock = new Object();
public QB() {
tList = new Vector<Thread>();
}
public synchronized void start() {
for(int i = 0; i < 1; i++) {
final int id = i;
Thread t = new Thread("Thread " + id) {
public void run() {
load(id);
}
};
tList.add(i, t);
t.start();
}
tMonitor();
waitUntilFinished();
}
private void tMonitor() {
Thread cmt = new Thread("T Monitor Thread") {
public void run() {
synchronized(waitingLock) {
while(tList.size() > 0) {
try {
sleep(10000);
} catch(Exception e) {
e.printStackTrace();
}
}
waitingLock.notifyAll();
}
}
};
cmt.start();
}
private void waitUntilFinished() {
synchronized(waitingLock) {
while(!isShutDown()) {
try {
waitingLock.wait();
} catch(Exception e) {
e.printStackTrace();
}
}
}
}
private synchronized void load(int id) {
try {
System.out.println("blocked here");
// some work done here
removeFromTList(id);
} catch(Exception e) {
e.printStackTrace();
}
}
public synchronized boolean isShutDown() {
return shutdown;
}
}
}
The first problem I see is that QB#start() is synchronized on the instance of QB.
Inside the thread t that you are trying to spawn, load(id) is also synchronized on the same instance of QB. So when you call t.start() the t thread blocks until QB#start() finishes.
Presumably, at the end of the QB#start() method, QB#waitUntilFinished() is supposed to wait for all the t threads to finish, but they can't even enter the QB#load method because they're still waiting for the QB#start() method to release the lock on the QB instance.
So, circular deadlock.
Edit:
Ok, now that we see how the threads are removed from tList the bug is fully revealed.
If the index 0 thread finishes first then it will remove itself from the list. That means when the index 1 thread finishes, it will remove the 1th position from the Vector but that does not point to itself anymore. It is removing the #2 thread. Sooner or later you are going to get an exception when the remove happens because it is going to be removing an invalid index.
You need to remove items from the Vector by address and not by position:
tList.remove(this);
That will remove the current thread from the list. You should also just do an add(t) instead of an add(i t) in the start loop:
tList.add(t);
You now don't need the id position passed into your thread at all.
I don't see where you are removing the finished threads from your tList. I see a definition (not that you edited your OP) of a removeFromTList() method but I don't see it used anywhere. In tMonitor you are in a while loop here:
while(tList.size() > 0) {
try {
sleep(10000);
} catch(Exception e) {
e.printStackTrace();
}
}
// you never get to this line
        waitingLock.notifyAll();
But I don't see anything that removes the thread from the list. Maybe when the threads each finish they are supposed to remove themselves?
If tMonitor thread never gets out of that loop then it never calls:
waitingLock.notifyAll();
So the main thread will hang forever in waitUntilFinished();.
synchronized(waitingLock) {
while(!isShutDown()) {
try {
waitingLock.wait();
} catch(Exception e) {
e.printStackTrace();
}
}
Also, you don't want to do a sleep in tMonitor() because you are in a synchronized block. You should be doing a:
waitingLock.wait(10000);
Nothing will ever notify it but it's bad form to hold the lock like that in a sleep.

Categories