I am writing Java software, that has a single thread, which listens to external buttons being pressed. If the button is pressed, the thread informs other threads, but otherwise it just sleeps.
My model is to use interrupt-driven design. Ideally I would like to make
a thread sleep as long as no button is pressed. When the button is pressed I would like the thread to do some work and go back to sleep.
Could anyone confirm / correct the following implementation?
// This is a code that interrupt-driven thread will execute
public void run() {
while (true) {
try {
Thread.sleep(1000); // Sleeps only for 1s. How to sleep indefinitely?
} catch (InterruptedException exception) {
process(exception); // Doing some work
// then going back to sleep using the while loop
}
}
}
Also, after each button click in the terminal I get a message
I/O exception raised from stop()
What does this message mean (i.e why is it printed if I catch the exception)? Can I avoid the terminal to print it?
It is generally considered a code smell if you use exceptions to control your program flow.
The correct solution to this problem is to use a BlockingQueue of events that the event handler reads from. This is commonly called a producer/consumer.
public class TwoThreads {
public static void main(String args[]) throws InterruptedException {
System.out.println("TwoThreads:Test");
new TwoThreads().test();
}
// The end of the list.
private static final Integer End = -1;
static class Producer implements Runnable {
final BlockingQueue<Integer> queue;
public Producer(BlockingQueue<Integer> queue) {
this.queue = queue;
}
#Override
public void run() {
try {
for (int i = 0; i < 1000; i++) {
queue.add(i);
Thread.sleep(1);
}
// Finish the queue.
queue.add(End);
} catch (InterruptedException ex) {
// Just exit.
}
}
}
static class Consumer implements Runnable {
final BlockingQueue<Integer> queue;
public Consumer(BlockingQueue<Integer> queue) {
this.queue = queue;
}
#Override
public void run() {
boolean ended = false;
while (!ended) {
try {
Integer i = queue.take();
ended = i == End;
System.out.println(i);
} catch (InterruptedException ex) {
ended = true;
}
}
}
}
public void test() throws InterruptedException {
BlockingQueue<Integer> queue = new LinkedBlockingQueue<>();
Thread pt = new Thread(new Producer(queue));
Thread ct = new Thread(new Consumer(queue));
// Start it all going.
pt.start();
ct.start();
// Wait for it to finish.
pt.join();
ct.join();
}
}
Don't let yourself be confused by how much code this is - most of it is just wrapping. The core functionality is:
At start - create a BlockingQueue and share it between the two threads.
BlockingQueue<Integer> queue = new LinkedBlockingQueue<>();
Thread pt = new Thread(new Producer(queue));
Thread ct = new Thread(new Consumer(queue));
When an event happens, post to the queue.
queue.add(i);
The event handler feeds off the queue.
while (!ended) {
try {
Integer i = queue.take();
Note that take here will block until an event is posted or an interrupt occurrs.
You can use
Thread.sleep(Long.MAX_VALUE); // more than the life of your computer
or
synchronized(this) {
wait();
}
or this wake on interrupt but doesn't throw an exception
LockSupport.park();
However a more elegant solution is likely to be to use an ExecutorService is designed to be a sleeping thread pool which wakes when you give it work to do.
ExecutorsService executor = Executors.newSingleThreadExecutor();
// when you want it to do something
executor.submit(this::process);
Note: you should consider how you want to handle exceptions. In the example in your question, an exception or error will kill the thread and it will stop running. In my example it won't kill the thread pool but the actual exception could be lost. For this reason I suggest you write it like this.
executor.submit(() -> {
try {
process();
} catch(Throwable t) {
LOGGER.warning(t);
}
});
Note: instead of just calling process and it having to figure out what you want to do you can write it like this.
doSomething(string, number, pojo);
That way you can see what data you expect the background thread to work on.
For comparison, here is the TwoThread example using the current thread as a producer and an Executor Service.
public class TwoThreadsJava5 {
public static void main(String args[]) throws InterruptedException {
System.out.println("TwoThreads:Test - Java 5.0 style");
ExecutorService executor = Executors.newSingleThreadExecutor();
for (int i = 0; i < 1000; i++) {
final int finalI = i;
executor.submit(() -> {
try {
System.out.println(finalI);
} catch (Throwable t) {
t.printStackTrace();
}
});
}
executor.shutdown();
executor.awaitTermination(1, TimeUnit.MINUTES);
}
}
And in Java 8 you could write
public class TwoThreadsJava8 {
public static void main(String args[]) throws InterruptedException {
System.out.println("TwoThreads:Test - Java 8 style");
IntStream.range(0, 1000)
.parallel()
.forEach(System.out::println);
}
}
Related
package threadShareResource1;
public class NonSynchro1 {
private int sum = 0;
public static void main(String[] args) {
NonSynchro1 n = new NonSynchro1();
n.task();
System.out.println(n.getSum());
}
public synchronized void sumAddOne(){
sum++;
}
public void task(){
for (int i = 0; i < 100; i++) {
new Thread(new Runnable(){
#Override
public void run() {
sumAddOne();
}
}).start();
/* try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
} */
}
}
public int getSum() {
return sum;
}
}
Without the commented part of code, the program has data corruption, which is not 100 every time I run it. But I thought the synchronized keyword should acquires a lock on the sumAddOne method, which is the critical region of my program, allowing one thread accessing this method every time.
I've try to use ExecutorService as well, but it doesn't give 100 all the runs.
public void task(){
ExecutorService s = Executors.newCachedThreadPool();
for (int i = 0; i < 100; i++) {
s.execute(new Thread(new Runnable(){
#Override
public void run() {
sumAddOne();
}
}));
}
s.shutdown();
while(!s.isTerminated()){}
}
In Task(), you start 100 threads (which is a lot) and each one is to add 1 to sum.
But when Task is done all you know is that 100 threads are in some process of having started. You don't block before calling println(), so how do you know all the threads have completed?
The sleep probably "prevents the corruption" just because it gives the system time to finish launching all the threads.
Beyond that you are using Synchronized correctly. Any place multiple threads may write to the same variable you need it and, in general (simplifying), you don't need it if you are only reading.
Synchronised keyword is used correctly, the problem is that you are not waiting for the threads to finish. Here is a possible solution:
public class NonSynchro1 {
private static final ExecutorService executorService = Executors.newCachedThreadPool();
private int sum = 0;
public static void main(String[] args) {
NonSynchro1 n = new NonSynchro1();
n.task();
System.out.println(n.getSum());
executorService.shutdown();
}
public synchronized void sumAddOne() {
sum++;
}
public void task() {
List<Callable<Object>> callables = new ArrayList<>();
for (int i = 0; i < 100; i++) {
callables.add(() -> {
sumAddOne();
return null;
});
}
List<Future<Object>> futures;
try {
futures = executorService.invokeAll(callables);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
futures.forEach(future -> {
try {
future.get();
} catch (ExecutionException | InterruptedException e) {
throw new RuntimeException(e);
}
});
}
public int getSum() {
return sum;
}
}
First we create a list of callables - a list of functions that will be executed in parallel.
Then we invoke them on the executor service. newCachedThreadPool I have used here, by default has 0 threads, it will create as many as necessary to execute all passed callables, the threads will be killed after being idle for a minute.
Finally, in the for-each loop we resolve all futures. get() call will block until the function was executed by the executor service. It will also throw exception if it was thrown inside the function (without calling get() you would not see such exception at all).
Also, it is a good idea to shutdown the executor service when you want to terminate the program gracefully. In this case, it is just executorService.shutdown() at the end of main method. If you don't do this, the program will terminate after a minute when idle threads are killed. However, if different executor service, threads might not be killed when idle, in which case the program would never terminate.
Just for completeness sake: Here's a solution showing how the original program can be made to wait for all threads to finish by joining them:
for (Thread t : n.task())
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
which requires task to return the threads it creates. In this case we don't need to complicate things with caching managers or collections: a simple array will do. Here's the complete class:
public class TestSynchro1 {
private int sum = 0;
public synchronized void sumAddOne() {
sum++;
}
public Thread[] task(int n) {
Thread[] threads = new Thread[n];
for (int i = 0; i < n; i++) {
(threads[i] = new Thread(new Runnable() {
#Override
public void run() {
sumAddOne();
}
})).start();
}
return threads;
}
public static void main(String[] args) {
TestSynchro1 n = new TestSynchro1();
for (Thread t : n.task(100))
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(n.sum);
}
}
I'm trying to come with a solution for a thread to pause and resume exactly where it was left off.
So here's a sample code emulating my problem: 2 threads are running in the background: taskThread & busyThread. When busyThread is in system is busy area, taskThread must alt/pause immediately and resume exactly where it was left off. Example, if taskThread was paused at task C (finished) it should resume at D.
I tried to use wait, notify on taskThread but without success.
public class Test
{
private Thread taskThread;
private Thread busyThread;
public static void main(String args[]) throws Exception
{
Test t = new Test();
t.runTaskThread();
t.runBusyThread();
}
public void runTaskThread()
{
taskThread = new Thread(new Runnable(){
#Override
public void run()
{
for (int x=0; x<100; x++)
{
try
{
System.out.println("I'm doing task A for process #"+x);
Thread.sleep(1000);
System.out.println("I'm doing task B for process #"+x);
Thread.sleep(200);
System.out.println("I'm doing task C for process #"+x);
Thread.sleep(300);
System.out.println("I'm doing task D for process #"+x);
Thread.sleep(800);
System.out.println("\n\n");
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}});
taskThread.start();
}
public void runBusyThread()
{
busyThread = new Thread(new Runnable(){
#Override
public void run()
{
while (true)
{
Random rand = new Random();
int randomNum = rand.nextInt(1000);
if (randomNum<400)
{
System.out.println("Wait...system is busy!!!");
try
{ //what should come here to to signal taskThread to paused
Thread.sleep(3000);
//what should come here to to signal taskThread to resume
} catch (InterruptedException e)
{
}
} else
{
try
{
Thread.sleep(300);
} catch (InterruptedException e)
{
}
}
}
}});
busyThread.start();
}
}
There are two very useful classes in concurrency package - CountDownLatch and CyclicBarrier. If you need this behaviour only once, you probably want the first one (as it cannot be reset).
Thread 1 will await until notified by thread 2. Once it was counted down to 0, thread 1 will never block again at await():
CountDownLatch cdl = new CountDownLatch(1);
// thread 1:
cdl.await();
// thread 2:
cdl.countDown();
Threads will block at await() until there are exactly two threads waiting:
CyclicBarrier barrier = new CyclicBarrier(2);
// both threads:
barrier.await();
EDIT:
Here is what I came up with when modifying your code, however it is unclear to me whether it is expected behaviour.
Note a volatile keyword on the CountDownLatch - it is very important here, otherwise taskThread may cache the initial object (new CountDownLatch(0)) and hence never block.
public class Test {
private Thread taskThread;
private Thread busyThread;
private volatile CountDownLatch cdl = new CountDownLatch(0);
public static void main(String args[]) throws Exception {
Test t = new Test();
t.runTaskThread();
t.runBusyThread();
}
public void runTaskThread() {
taskThread = new Thread(() -> {
for (int x = 0; x < 100; x++) {
waitIfSystemBusy();
System.out.println("I'm doing task A for process #" + x);
sleep(1000);
waitIfSystemBusy();
System.out.println("I'm doing task B for process #" + x);
sleep(200);
waitIfSystemBusy();
System.out.println("I'm doing task C for process #" + x);
sleep(300);
waitIfSystemBusy();
System.out.println("I'm doing task D for process #" + x);
sleep(800);
System.out.println("\n\n");
}
});
taskThread.start();
}
public void runBusyThread() {
busyThread = new Thread(() -> {
while (true) {
Random rand = new Random();
int randomNum = rand.nextInt(1000);
if (randomNum < 400) {
System.out.println("Wait...system is busy!!!");
cdl = new CountDownLatch(1); // signal taskThread to pause
sleep(3000);
cdl.countDown(); // signal taskThread to resume
} else {
sleep(300);
}
}
});
busyThread.start();
}
private void waitIfSystemBusy() {
try {
cdl.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
private static void sleep(int millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
It would be done using the deprecated methods Thread.suspend/resume.
They are deprecated as they are deadlock prone, whereas concurrency mechanisms like locks behave in a designed explicit manner (but still deadlock prone).
I would suggest create a class that implements Runnable which simply keep track of the stages you are in
just as an example (please change accordingly)
class MyRunnable implements Runnable {
private int stage = 0; // if you want it gloabally, then use static
#Override
public void run() {
try{
switch(stage){
case 1:
System.out.println("1");
stage++;
case 2:
System.out.println("2");
Thread.sleep(2000);
stage++;
default:
stage = 0;
}
}catch (Exception e){
}
}
}
now to use such class you just need to create a new thread
for example:
public static void main(String[] args) throws Exception{
MyRunnable myRunnable=new MyRunnable();
new Thread(myRunnable).start(); //it prints 1
Thread.sleep(1000);
new Thread(myRunnable).start(); //prints 2 follow by 2 sec sleep
}
NOTE:
this example wasn't intended to answer the question exactly but rather show a logic how it can be done.
EDIT 1:
what should come here to to signal taskThread to paused
taskThread.interupt();
what should come here to to signal taskThread to resume
taskThread=new Thread(myRunnable);
taskThread.start();
Instead of sleep() I would prefer wait() and notifyAll().
have a Boolean systemBusy, implement get and set methods;
now in thread1
run(){
synchronize(something){
while(isSystemBusy()){
try{
wait();}
catch{}
}
}
}
and on the other thread
run(){
setSystemBusy(true);
//piece of code
//task finished
notifyAll();
setSystemBusy(false);
}
you can use this in multiple waiting threads just remember to set appropriate while condition false after notify all.
If any of the submitted thread is throwing exception its not returning the exception.
I want to write a piece of code for my project where in if any of the thread execution is failed it should throw the exception there & it should stop all the running & scheduled threads.
ExecutorService executorService = Executors.newFixedThreadPool(10);
for (int i = 0; i < 10; i++) {
Thread t = new Thread(new MyObject());
executorService.submit(t);
}
I wrote MyObject like this..,
public class MyObject implements Runnable {
public void run() {
throw new NullPointerException("Sample NullPointerException");
}
}
Is this the correct implementation for my goal...?????
i want to achieve that goal please give me some pointers.
Thanks In Advance....!!
Here is something you can consider about. Here I am using CallableTask instead of Thread.
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(10);
Set<Future<Void>> futureSet = new HashSet<Future<Void>>();
for (int i = 0; i < 9; i++) {
CallableTask1 task = new CallableTask1();
futureSet.add(executorService.submit(task));
}
CallableTask2 task2 = new CallableTask2();
futureSet.add(executorService.submit(task2));
boolean flag = false;
for (Future<Void> future : futureSet ) {
try {
future.get();
} catch (InterruptedException e) {
System.out.println("Interrupted");
} catch (ExecutionException e) {
System.out.println("Exception thrown from the thread");
flag = true;
break;
}
}
if(flag) {
for (Future<Void> future : futureSet) {
future.cancel(true);
}
}
}
Here I am using two classes to demonstrate this is working. When one task throw an exception the forever running task is also stop running.
class CallableTask1 implements Callable<Void> {
#Override
public Void call() throws Exception {
throw new NullPointerException("Sample NullPointerException");
}
}
class CallableTask2 implements Callable<Void> {
#Override
public Void call() throws Exception {
while (true){
System.out.println("THIS IS RUNNING");
Thread.sleep(5000);
}
}
}
But this has it's own limitations. This code will wait for it's turn to throw an exception because of "future.get()" executed sequentially.
Best case : Throw an exception in first future.get() and other tasks will be cancelled.
Worst case : Throw an exception in the last future.get() and by the time throw an exception all other tasks done with execution.
Optimizing : Identify the tasks that can throw an exception and wait for those tasks only to cancel all the other tasks.
If your run methods has while in it then best way share a flag and break on it. Check this answer for more information.
I am trying an example of multi threading in java. There was an example on multithreading Synchronization in Java Complete reference 7th Edition. The example works fine. but when i slightly add a line to create another thread of the same class this does not work. Could some please let me know why this is happening. The example is given below. The below code is a classic exacple of producer and consumer. Where there is a single producer it works fine when i have 2 producers then it will fail. It just puts till 15 and stops.
class Q {
int n;
boolean valueSet = false;
synchronized int get() {
while (!valueSet) {
try {
wait();
} catch (InterruptedException e) {
System.out.println("InterruptedException caught");
}
}
System.out.println("Got: " + n);
valueSet = false;
notify();
return n;
}
synchronized void put(int n) {
while (valueSet) {
try {
wait();
} catch (InterruptedException e) {
System.out.println("InterruptedException caught");
}
}
this.n = n;
valueSet = true;
System.out.println("Put: " + n);
notify();
}
}
class Producer implements Runnable {
Q q;
Producer(Q q) {
this.q = q;
new Thread(this, "Producer").start();
//new Thread(this, "Producer2").start();
}
public void run() {
int i = 0;
while (true) {
q.put(i++);
}
}
}
class Consumer implements Runnable {
Q q;
Consumer(Q q) {
this.q = q;
new Thread(this, "Consumer").start();
}
#Override
public void run() {
while (true) {
q.get();
}
}
}
public class PCFixed {
public static void main(String[] args) {
Q q = new Q();
Producer P1 = new Producer(q);
new Consumer(q);
Producer P2 = new Producer(q);
System.out.println("Press Control-C to stop.");
}
}
Q is written to only accept one value at a time. You need to change put to be a boolean method - it returns true if valueset is true and then proceeds as normal, and returns false if valueset is false and returns without doing anything. Then the methods calling put will need to keep retrying until they get a true response. This way multiple consumers can use the same Q object without interfering with each other.
A better solution if you're using multiple producers is to use a ConcurrentLinkedQueue, which is a thread-safe queue. The producers will offer integers to the queue, and the consumers will poll the queue for integers. Multiple producers can simultaneously offer integers without interfering with each other, and multiple consumers can simultaneously poll integers without interfering with each other.
The example of concurrency you provide uses a single boolean flag to check whether there is a signal or not.
So this is more of a Semaphore arrangement than a producer consumer arrangement. It is too simplistic to deal with an arbitrary number of Threads.
If you really want to use producer consumer you are going to need a queue that holds more than one item.
static final AtomicBoolean run = new AtomicBoolean(true);
static class Producer implements Runnable {
final BlockingQueue<String> blockingQueue;
public Producer(BlockingQueue<String> blockingQueue) {
this.blockingQueue = blockingQueue;
}
#Override
public void run() {
while (run.get()) {
blockingQueue.add("Value from " + Thread.currentThread().getName());
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
//doesn't matter.
}
}
}
}
static class Consumer implements Runnable {
final BlockingQueue<String> blockingQueue;
public Consumer(BlockingQueue<String> blockingQueue) {
this.blockingQueue = blockingQueue;
}
#Override
public void run() {
while (run.get()) {
final String item;
try {
item = blockingQueue.take();
} catch (InterruptedException ex) {
return;
}
System.out.println(item);
}
}
}
public static void main(String[] args) throws InterruptedException {
final LinkedBlockingQueue<String> lbq = new LinkedBlockingQueue<>();
final ExecutorService executorService = Executors.newCachedThreadPool();
executorService.submit(new Consumer(lbq));
for (int i = 0; i < 10; ++i) {
executorService.submit(new Producer(lbq));
}
Thread.sleep(10000);
run.set(false);
executorService.shutdownNow();
}
This simple example uses a LinkedBlockingQueue to post events to and read events from.
The Producer puts Strings into the queue with it's own Thread name (they do this every 100ms). The Consumer takes from the queue and prints the String.
The queue is a BlockingQueue so the take method will block if the queue is empty.
You can easily change the number of Producers and Consumers by changing the loops that add items to the ExecutorService. Experiment, see how it works.
The AtomicBoolean flag allows the program to shutdown all the child processes spawned.
Replace each occurrence of notify with notifyAll.
How to pass parameter to an already running thread in java -- not in the constructor, & probably without using wait() (possible ??)
Something similar to a comment in How can I pass a parameter to a Java Thread?
Do you mean passing a parameter to an already running thread ? Because all the current answers are about passing parameters to new threads... – Valentin Rocher May 18 '09 at 10:43
[edited]
yes, I was looking for something like the producer/consumer pattern.
I wanted something like a thread in which has the processing & is ready
for keyboard input. The other thread is just to monitor network and pass
on the received text to the processing thread.
Maybe what you really need is blocking queue.When you create the thread, you pass the blocking queue in and the thread should keep checking if there is any element in the queue. Outside the thread, you can put elements to the queue while the thread is "running". Blocking queue can prevent the thread from quit if their is nothing to do.
public class Test {
public static void main(String... args) {
final BlockingQueue<String> queue = new LinkedBlockingQueue<String>();
Thread running = new Thread(new Runnable() {
#Override
public void run() {
while (true) {
try {
String data = queue.take();
//handle the data
} catch (InterruptedException e) {
System.err.println("Error occurred:" + e);
}
}
}
});
running.start();
// Send data to the running thread
for (int i = 0; i < 10; i++) {
queue.offer("data " + i);
}
}
}
The "other thread" will have its own life, so you can't really communicate with it / pass parameters to it, unless it actively reads what you gives to it.
A thread which you allows you to communicate with it typically reads data from some buffered queue.
Have a look at ArrayBlockingQueue for instance, and read up on the Consumer-Producer pattern.
public class T1 implements Runnable {
//parameter of thread T1
public static AtomicBoolean flag = new AtomicBoolean();
#Override
public void run() {
}
}
public class T2 implements Runnable {
#Override
public void run() {
//parameter to an already running thread
T1.flag.set(true);
}
}
What about such way:
class TestRun implements Runnable
{
private int testInt = -1;
public void setInt(int i)
{
this.testInt = i;
}
#Override
public void run()
{
while (!isFinishing())
{
System.out.println("Working thread, int : " + testInt);
try
{
Thread.sleep(2500);
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
.....
TestRun first = new TestRun();
TestRun second = new TestRun();
(new Thread(first)).start();
(new Thread(second)).start();
try
{
Thread.sleep(5000);
}
catch (InterruptedException e)
{
}
first.setInt(101);
second.setInt(102);