for (final ArrayList<SmartPhone> smartPhones : smartPhonesCluster) {
new Thread(new Runnable() {
#Override
public void run() {
for (SmartPhone smartPhone : smartPhones) {
Queue<SmartPhoneTask> tasks = smartPhone.getSystem()
.getTaskQue();
SmartPhoneTask task = null;
assert tasks != null;
try {
while (!tasks.isEmpty()) {
task = tasks.poll(); // This is the line throwing the exception (GlobalNetwork.java:118)
assert task != null;
task.execute();
task.onTaskComplete();
}
} catch (RuntimeException e) {
e.printStackTrace();
}
}
}
}).start();
}
And log:
java.util.NoSuchElementException
at java.util.LinkedList.remove(LinkedList.java:788)
at java.util.LinkedList.removeFirst(LinkedList.java:134)
at java.util.LinkedList.poll(LinkedList.java:470)
at com.wtsang02.reu.botnet.network.GlobalNetwork$1.run(GlobalNetwork.java:118)
at java.lang.Thread.run(Thread.java:662)
java.lang.NullPointerException
Exception in thread "Thread-299" java.lang.AssertionError
at com.wtsang02.reu.botnet.network.GlobalNetwork$1.run(GlobalNetwork.java:119)
at java.lang.Thread.run(Thread.java:662)
line 118 points to:
task=tasks.poll();
How to solve this? Queue is LinkedList implemenation if that makes a difference.
LinkedList is not thread-safe, so you need external synchronization if you access a Linkedlist on more than one thread. This synchronization is on some object (a synchronized method is just shorthand for "synchronize on this"), and both the gets and the puts must be synchronized on the same object. You're definitely doing that here, since you create a new thread for each SmartPhone, and then access that phone's LinkedList from there.
If one thread puts into the list while synchronized on someObject1, and then another thread reads that list while synchronized on someObject2, then this does not count as external synchronization -- the code is still broken.
Even if you used a thread-safe collection, it'd be possible to hit this exception if multiple threads are emptying the queue at the same time. For instance, imagine this:
thread A: put e into queue1
thread B: queue1.isEmpty()? No, so go on
thread C: queue1.isEmpty()? No, so go on
thread B: queue1.poll() // works
thread C: queue1.poll() // NoSuchElementException
You should use BlockingQueue, whose poll() method will return null if there are no more elements in the list. Keep pulling until you get a null, and then break the loop.
Related
I want to have a thread which does some I/O work when it is interrupted by a main thread and then go back to sleep/wait until the interrupt is called back again.
So, I have come up with an implementation which seems to be not working. The code snippet is below.
Note - Here the flag is a public variable which can be accessed via the thread class which is in the main class
// in the main function this is how I am calling it
if(!flag) {
thread.interrupt()
}
//this is how my thread class is implemented
class IOworkthread extends Thread {
#Override
public void run() {
while(true) {
try {
flag = false;
Thread.sleep(1000);
} catch (InterruptedException e) {
flag = true;
try {
// doing my I/O work
} catch (Exception e1) {
// print the exception message
}
}
}
}
}
In the above snippet, the second try-catch block catches the InterruptedException. This means that both of the first and second try-catch block are catching the interrupt. But I had only called interrupt to happen during the first try-catch block.
Can you please help me with this?
EDIT
If you feel that there can be another solution for my objective, I will be happy to know about it :)
If it's important to respond fast to the flag you could try the following:
class IOworkthread extends Thread {//implements Runnable would be better here, but thats another story
#Override
public void run() {
while(true) {
try {
flag = false;
Thread.sleep(1000);
}
catch (InterruptedException e) {
flag = true;
}
//after the catch block the interrupted state of the thread should be reset and there should be no exceptions here
try {
// doing I/O work
}
catch (Exception e1) {
// print the exception message
// here of course other exceptions could appear but if there is no Thread.sleep() used here there should be no InterruptedException in this block
}
}
}
}
This should do different because in the catch block when the InterruptedException is caught, the interrupted flag of the thread is reset (at the end of the catch block).
It does sound like a producer/consumer construct. You seem to kind of have it the wrong way around, the IO should be driving the algorithm. Since you stay very abstract in what your code actually does, I'll need to stick to that.
So let's say your "distributed algorithm" works on data of type T; that means that it can be described as a Consumer<T> (the method name in this interface is accept(T value)). Since it can run concurrently, you want to create several instances of that; this is usually done using an ExecutorService. The Executors class provides a nice set of factory methods for creating one, let's use Executors.newFixedThreadPool(parallelism).
Your "IO" thread runs to create input for the algorithm, meaning it is a Supplier<T>. We can run it in an Executors.newSingleThreadExecutor().
We connect these two using a BlockingQueue<T>; this is a FIFO collection. The IO thread puts elements in, and the algorithm instances take out the next one that becomes available.
This makes the whole setup look something like this:
void run() {
int parallelism = 4; // or whatever
ExecutorService algorithmExecutor = Executors.newFixedThreadPool(parallelism);
ExecutorService ioExecutor = Executors.newSingleThreadExecutor();
// this queue will accept up to 4 elements
// this might need to be changed depending on performance of each
BlockingQueue<T> queue = new ArrayBlockingQueue<T>(parallelism);
ioExecutor.submit(new IoExecutor(queue));
// take element from queue
T nextElement = getNextElement(queue);
while (nextElement != null) {
algorithmExecutor.submit(() -> new AlgorithmInstance().accept(nextElement));
nextElement = getNextElement(queue);
if (nextElement == null) break;
}
// wait until algorithms have finished running and cleanup
algorithmExecutor.awaitTermination(Integer.MAX_VALUE, TimeUnit.YEARS);
algorithmExecutor.shutdown();
ioExecutor.shutdown(); // the io thread should have terminated by now already
}
T getNextElement(BlockingQueue<T> queue) {
int timeOut = 1; // adjust depending on your IO
T result = null;
while (true) {
try {
result = queue.poll(timeOut, TimeUnits.SECONDS);
} catch (TimeoutException e) {} // retry indefinetely, we will get a value eventually
}
return result;
}
Now this doesn't actually answer your question because you wanted to know how the IO thread can be notified when it can continue reading data.
This is achieved by the limit to the BlockingQueue<> which will not accept elements after this has been reached, meaning the IO thread can just keep reading and try to put in elements.
abstract class IoExecutor<T> {
private final BlockingQueue<T> queue;
public IoExecutor(BlockingQueue<T> q) { queue = q; }
public void run() {
while (hasMoreData()) {
T data = readData();
// this will block if the queue is full, so IO will pause
queue.put(data);
}
// put null into queue
queue.put(null);
}
protected boolean hasMoreData();
protected abstract T readData();
}
As a result during runtime you should at all time have 4 threads of the algorithm running, as well as (up to) 4 items in the queue waiting for one of the algorithm threads to finish and pick them up.
I'm not getting expected result for below program, I was expecting both producer and consumer method should execute in some sequence, but for some reason only producer method is getting executed.
I have two question here :
I'm not able to understand this behaviour.
Joining both thread together in last line of main method is working properly, I'm not able to understand difference between both.
public class ProducerConsumer {
List<Integer> data = new ArrayList<>();
synchronized void produce() throws InterruptedException {
for (int i = 0; i < 10; i++) {
System.out.println("Producing");
data.add(i);
}
wait();
}
synchronized void consume() throws InterruptedException {
System.out.println("Consuming");
data.clear();
notify();
}
public static void main(String[] args) throws InterruptedException {
ProducerConsumer pc = new ProducerConsumer();
Runnable r2 = ()-> {
try {
pc.produce();
} catch (InterruptedException e) {
e.printStackTrace();
}
};
Thread thread1 = new Thread(r2);
thread1.start();
thread1.join();
Runnable r1 = () -> {
try {
pc.consume();
} catch (InterruptedException e) {
e.printStackTrace();
}
};
Thread thread = new Thread(r1);
thread.start();
thread.join();
}
Output :
Producing
Producing
Producing
Producing
Producing
Producing
Producing
Producing
Producing
Producing
The produce() method ends with wait(). So it blocks until some thread notifies it.
The only thread that does that is the consumer thread. But the consumer thread is started by the main method only after the producer thread has ended. And it can't end until it's been notified. So you have a deadlock.
If you join() only after the two threads are started, then the consumer thread can start without having to wait for the producer thread to be finished. That still doesn't make the program correct since
you have no guarantee that the producer thread will execute first
calling wait() at then end is useless
calling wait() out of a loop checking for a condition is incorrect
if you want methods to execute in sequence, using threads is useless. You can do everything from the main thread.
1) A notify() call does not do anything at all. Unless some other thread is already waiting to be notified.
It's up to you to guarantee that any time one of your threads calls wait(), some other thread will notify() the same object some time after the wait() has begun.
Oracle's Guarded Blocks Tutorial does a pretty good job of explaining exactly how o.wait() and o.notify() work, and it explains how to establish that guarantee.
2) There is virtually no reason to do this:
Thread t = new Thread(r);
t.start();
t.join();
Your program will use less CPU, and it will use less memory, and it will accomplish exactly the same thing if you just call r.run() instead. The entire point of threads is to allow different things to happen concurrently, and there is no concurrency if one thread joins a new thread immediately after creating it. The new Thread object is wasted unless you do something like this with it:
Thread t = new Thread(r);
t.start();
doSomethingElseWhileThread_t_isRunning();
t.join();
3) wait() and notify() are a very low-level means of communicating between threads. Your code will be easier to read and understand if you use higher-level synchronization objects that are built on top of wait() and notify() instead of directly
calling them.
A java.util.concurrent.ArrayBlockingQueue instance would be especially well suited to a "producer/consumer" application.
public class MyClass {
private List<Integer> resources = new ArrayList<>();
public synchronized Integer getAndRemoveResourceOrWait(Integer requestedResource) throws InterruptedException {
while(resources.stream().anyMatch((r) -> { return r >= requestedResource; })) {
wait();
}
Integer found = resources.stream().findFirst((r) -> {
return r >= requestedResource;
}).get();
resources.remove(found);
return found;
}
public void addResource(Integer resource) {
resources.add(resource);
notifyAll();
}
}
Thread "A" episodically invokes addResource with random value.
A few another threads actively invokes getAndRemoveResourceOrWait.
What I need to do to let method getAndRemoveResourceOrWait work concurrently?
For example, thread "X" invokes getAndRemoveResourceOrWait with variable 128 which does not exists in resources collection. So, it become waiting for it. While it is waiting, thread "Y" invokes getAndRemoveResourceOrWait with variable 64 and it exists in resources collection. Thread "Y" should not wait for thread "X" to complete.
What I need to do to let method getAndRemoveResourceOrWait work concurrently?
It simply needs to run on a different thread to the one that calls addResource(resource).
Note that getAndRemoveResource is a blocking (synchronous) operation in the sense that the thread making the call is blocked until it gets the answer. However one thread that is calling getAndRemoveResource does not block another thread calling getAndRemoveResource. The key is that the wait() call releases the mutex, and then reacquires it when the mutex is notified. What will happen here is that a notifyAll will cause all waiting threads to way up, one at a time.
However, there is a bug on your addResource method. The method needs to be declared as synchronized. If you don't call notifyAll() while the current thread holds the mutex for on this, you will get an exception. (And this is also necessary to ensure that the updates to the shared resources object are visible ... in both directions.)
Also, this implementation is not going to scale well:
Each waiting thread will scan the entire resource list on every update; i.e. on every call to addResource.
When a waiting thread finds a resource, it will scan the list twice more to remove it.
All of this is done while holding the mutex on the shared MyClass instance ... which blocks addResource as well.
UPDATE - Assuming that the Resource values are unique, a better solution would be to use replace ArrayList with TreeSet. This should work:
public class MyClass {
private TreetSet<Integer> resources = new TreeSet<>();
public synchronized Integer getAndRemoveResourceOrWait(
Integer resource) throws InterruptedException {
while (true) {
Integer found = resources.tailSet(resource, true).pollFirst();
if (found != null) {
return found;
}
wait();
}
}
public synchronized void addResource(Integer resource) {
resources.add(resource);
notifyAll();
}
}
(I also tried ConcurrentSkipListSet but I couldn't figure out a way to avoid using a mutex while adding and removing. If you were trying to remove an equal resource, it could be done ...)
I'm trying to figure out the best way to have multiple threads working from the same list of strings. For example, say I have a list of words, and I want multiple threads to work on printing out each word on this list.
Here is what I came up with. The thread uses a while loop, and while the iterator has next, it prints out and removes it from the list.
import java.util.*;
public class ThreadsExample {
static Iterator it;
public static void main(String[] args) throws Exception {
ArrayList<String> list = new ArrayList<>();
list.add("comet");
list.add("planet");
list.add("moon");
list.add("star");
list.add("asteroid");
list.add("rocket");
list.add("spaceship");
list.add("solar");
list.add("quasar");
list.add("blackhole");
it = list.iterator();
//launch three threads
RunIt rit = new RunIt();
rit.runit();
rit.runit();
rit.runit();
}
}
class RunIt implements Runnable {
public void run()
{
while (ThreadsExample.it.hasNext()) {
//Print out and remove string from the list
System.out.println(ThreadsExample.it.next());
ThreadsExample.it.remove();
}
}
public void runit() {
Thread thread = new Thread(new RunIt());
thread.start();
}
}
This seems to work, although I get some Exception in thread "Thread-2" Exception in thread "Thread-0" java.lang.IllegalStateException errors during the run:
Exception in thread "Thread-1" Exception in thread "Thread-0"
java.lang.IllegalStateException at
java.util.ArrayList$Itr.remove(ArrayList.java:864) at
RunIt.run(ThreadsExample.java:44) at
java.lang.Thread.run(Thread.java:745) java.lang.IllegalStateException
at java.util.ArrayList$Itr.remove(ArrayList.java:864) at
RunIt.run(ThreadsExample.java:44) at
java.lang.Thread.run(Thread.java:745)
Am I doing this correctly or is there a better way to have multiple threads working on the same pool of strings?
A better way to do this is to use a concurrent queue. The Queue interface is designed to hold elements in a structure prior to processing them.
final Queue<String> queue = new ConcurrentLinkedQueue<String>();
queue.offer("asteroid");
ExecutorService executorService = Executors.newFixedThreadPool(4);
executorService.execute(new Runnable() {
public void run() {
System.out.println(queue.poll());
}
});
executorService.shutdown();
Try creating the list as a synchronized list using List.synchronizedList
Update your code like this:
ArrayList<String> list = Collections.synchronizedList(new ArrayList<>());
Am I doing this correctly or is there a better way to have multiple threads working on the same pool of strings?
You are not doing it correctly. Your code is not properly synchronized, and therefore its behavior is not well defined. There are a great number of ways you could approach the general problem you present, but one way the issues in your particular code could be fixed would be to change RunIt.run() to properly synchronize:
public void run()
{
while (true) {
synchronized(ThreadsExample.it) {
if (ThreadsExample.it.hasNext()) {
//Print out and remove string from the list
System.out.println(ThreadsExample.it.next());
ThreadsExample.it.remove();
} else {
break;
}
}
}
}
Note here that the hasNext() check, retrieval of the next element, and removal of that element are all handled within the same synchronized block to ensure mutual consistency of these operations. On the other hand, the scope of that block is contained within the loop, so that different threads executing the loop concurrently each get a chance to execute.
Note, too, that although in this case all the threads synchronize on the Iterator object, that's basically just a convenience (for me). As long as they all synchronize on the same object, it doesn't matter so much which object that is.
I have done some research and could not find a solution to this problem.
From this topic Synchronization, When to or not to use? i understand i could use synchronized, but doing so doesn't solve the problem.
The case is that i have a method in which a Thread is used to create an ArrayList. In that same Thread another method is called after a BufferedReader has finished reading a file and the lines are being added to the first List.
In the second method the first list is being used to create the second List. When all that is done, the first method uses the second list.
This is somewhat the code i use, if there is something not clear please ask and i will try to provide the info needed.
public synchronized void theBaseList() {
Thread t = new Thread() {
#override
public void run() {
try(
while((line = br.readLine()) != null) {
firstList.add(line):
}
}
nextMethod();
currentObject = (Object[]) secondList.get(0); // throws an exception
}
}
};
t.start();
public synchronized void nextMethod() {
Thread t1 = new Thread(){
double objectListSize = calculateObjectListLength(firstList.size());
#override
public void run() {
try {
// create Objects
secondList.add(objects);
}
}
};
t1.start();
}
When i use a Thread in nextMethod() to create a new list of Objects from the items in the first list, i get an ArrayIndexOutOfBoundsException saying
Exception in thread "Thread-4" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
I avoided this by not using a Thread in the second method and all works fine.
If i do use 2 Threads and make both methods synchronized, it still throws the exception.
Is it possible or should i just settle by not using a Thread in the second method? I thought synchronized was for dealing with this sort of problems. I don't understand why it doesn't work.
Let's say your methods are defined in a class named Sample and you've created an instance mySample. This appears to be what your code is doing:
main thread calls mySample.theBaseList() and synchronizes by locking on mySample.
theBaseList() defines thread1 and starts it.
theBaseList() exits scope, thus unlocking on mySample.
thread1 reads in the lines of a file and adds them to list1 (these operations are not synchronized)
thread1 calls mySample.nextMethod()
mySample.nextMethod() synchronizes by locking on mySample
nextMethod() defines thread2 and starts it.
nextMethod() exits scope, thus unlocking on mySample.
* thread2 sets up list2 (these operations are not synchronized)
* thread1, having returned from nextMethod() reads from list2 (these operations are not synchronized)
The last two operations are the cause of your race condition.
In your case, using synchronized methods is perhaps too coarse grained. A better option may be to synchronize on the object on which both threads operate, secondList.
nextMethod();
synchronized(secondList) {
currentObject = (Object[]) secondList.get(0); // should no longer throw an exception
}
synchronized(secondList) {
// create Objects
secondList.add(objects);
}
EDIT:
synchronized(secondList) {
nextMethod();
secondList.wait();
currentObject = (Object[]) secondList.get(0); // should no longer throw an exception
}
synchronized(secondList) {
// create Objects
secondList.add(objects);
secondList.notifyAll();
}