Say, I've got a javafx.concurrent.Task nested into Thread, ie.:
Task task = new Task();
Thread thread = new Thread(task);
thread.start();
How can I in this situation pause and/or stop executing task nad resume its work?
There is no easy way, except using the deprecated suspend() and resume() methods on the Thread class.
In case you are sure your task doesn't enter synchronized code that would work
Otherwise you would have to have halt points in your task were you check if the Task has been halted and if so call wait() on some object to block the thread. A call to notify on the object would then wake the Thread up and resume. Below is a chunk of pseudo code for that approach.
Note that for this to work as expected you need check the halt variable frequently in the task code.
class MyTask{
volatile boolean halt = false;
Object o = new Object();
public void run(){
while(notDone) {
if (halt) halt();
}
}
private halt(){
synchronized (o){o.wait()}
}
public resume(){
halt = false;
synchronized (o){o.notify()}
}
public suspend(){
halt=true;
}
}
import java.io.IOException;
public class TestThread {
static class PausableRunnable implements Runnable{
volatile boolean shouldHalt = false;
private final Object lock=new Object();
public void run(){
while(true){
if(shouldHalt)halt();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.print(".");
}
}
private void halt(){
synchronized (lock){
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
void pause(){
shouldHalt = true;
}
void resume(){
synchronized (lock){
shouldHalt=false;
lock.notify();
}
}
}
public static void maipn(String[] args) throws IOException {
PausableRunnable pr = new PausableRunnable();
Thread t = new Thread(pr);
t.start();
while(true) {
char c = (char) System.in.read();
if (c == 'p') {
System.out.println("Pausing");
pr.pause();
}
if (c == 'r') {
System.out.println("Resuming");
pr.resume();
}
}
}
}
Related
I've been trying to make a simple implementation of Thread-Pool using Active Objects.
Here is my Main:
public static void main(String[] args){
MyThreadPool tp = new MyThreadPool(100,3);
tp.execute(()->{
try { Thread.sleep(5*1000); } catch (InterruptedException e) {}
System.out.println("42");
});
tp.shutDown();
}
The shutDown method is usually called first through the Main and therefore keeps the Active Objects "alive" unwantedly, but sometimes I get the wanted outcome.
Any idea why there is uncertainty about the result?
Below you can see the rest of the classes:
public class MyThreadPool {
ArrayBlockingQueue<Runnable> q;
ArrayBlockingQueue<ActiveObject> activeObjects;
volatile boolean stop;
AtomicInteger count;
Thread t;
Runnable stopTask;
public MyThreadPool(int capacity, int maxThreads) {
activeObjects = new ArrayBlockingQueue<>(maxThreads);
q = new ArrayBlockingQueue<>(capacity);
count = new AtomicInteger(0);
stopTask = ()->stop = true;
t=new Thread(()->{
//System.out.println("Thread-Pool Started");
while(!stop){
//if queue is empty it is gonna be a blocking call
try {
Runnable task = q.take();
if(task==stopTask)
stopTask.run();
else
//size() is atomic integer
if (count.get() < maxThreads) {
ActiveObject a = new ActiveObject(capacity);
activeObjects.put(a);
count.incrementAndGet();
a.execute(task);
}
//we will assign the next task to the least busy ActiveObject
else {
int minSize = Integer.MAX_VALUE;
ActiveObject choice = null;
for (ActiveObject a : activeObjects) {
if (a.size() < minSize) {
minSize = a.size();
choice = a;
}
}
choice.execute(task);
}
} catch (InterruptedException e) { }
}
//System.out.println("Thread-Pool Ended");
});
t.start();
}
//execute returns right away - just puts into the queue
public void execute(Runnable r ){
// if capacity is full it is gonna be a blocking call
if(!stop)
try { q.put(r); } catch (InterruptedException e) { }
}
public void shutDownNow(){
activeObjects.forEach(a->a.shutDownNow());
stop = true;
t.interrupt();
}
public void shutDown(){
activeObjects.forEach(a->a.shutDown());
execute(stopTask);
}
public class ActiveObject {
ArrayBlockingQueue<Runnable> q;
volatile boolean stop;
Thread t;
public ActiveObject(int capacity) {
q = new ArrayBlockingQueue<>(capacity);
t=new Thread(()->{
//System.out.println("Active Object Started");
while(!stop){
//if queue is empty it is gonna be a blocking call
try {
q.take().run();
} catch (InterruptedException e) { }
}
//System.out.println("Active Object Ended");
});
t.start();
}
//execute returns right away - just puts into the queue
public void execute(Runnable r ){
// if capacity is full it is gonna be a blocking call
if(!stop)
try { q.put(r); } catch (InterruptedException e) { }
}
public void shutDownNow(){
stop = true;
t.interrupt();
}
public void shutDown(){
execute(()->stop=true);
}
public int size(){
return q.size();
}
}
In your main method you create a thread pool (which also creates and starts tp.t thread), enqueue a task into tp.q, and then call tp.shutDown():
MyThreadPool tp = new MyThreadPool(100, 3);
tp.execute(() -> {...});
tp.shutDown();
Imagine that tp.shutDown() in the main thread is executed before the MyThreadPool.t thread processes the enqueued task:
activeObjects.forEach(a -> a.shutDown());
execute(stopTask);
here activeObjects is empty, you enqueue stopTask into tp.q, and main thread finishes.
Now we only have MyThreadPool.t thread, let's see what it does:
while (!stop) {
try {
Runnable task = q.take();
if (task == stopTask)
stopTask.run();
else
if (count.get() < maxThreads) {
ActiveObject a = new ActiveObject(capacity);
activeObjects.put(a);
count.incrementAndGet();
a.execute(task);
}
else {
...
}
} catch (InterruptedException e) {
}
}
At this point q contains 2 tasks: a normal task and stopTask.
In the first loop iteration the normal task is taken from q, and is given for processing to a newly created ActiveObject:
ActiveObject a = new ActiveObject(capacity);
activeObjects.put(a);
count.incrementAndGet();
a.execute(task);
new ActiveObject() also creates and starts its own internal ActiveObject.t thread.
The second loop iteration processes stopTask:
if (task == stopTask)
stopTask.run();
which sets stop = true.
As a result, the next check while (!stop) returns false and MyThreadPool.t thread finishes.
Now we only have ActiveObject.t thread, which hasn't been stopped:
while (!stop) {
try {
q.take().run();
} catch (InterruptedException e) {
}
}
here the thread will keep waiting on q.take() forever.
I have the following class, I usually run about 10 threads of it
public class MyClass implements Runnable {
private volatile Device device = null;
public MyClass(Device device) {
this.device = device;
}
#Override
public void run() {
while (true) { // <--- I do know that the "true" has to be changed to a Boolean
try {
Worker worker = new Worker();
worker.work();
System.out.println("Waiting 6 seconds!");
Thread.sleep(6 * 1000);
System.out.println("------------------------------------");
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println("Thread in program ended!");
}
}
and in my main I start the threads like this
for (int i = 0; i < 2; i++) {
(new Thread(new MyClass())).start();
}
This is a console based program. What is the most reliable way to end the program? I think the best way would be to change while (true) to while (Boolean) and somehow change that Boolean for all threads, then when the loop ends, the program will end gracefully.
Here i'm ending it by waiting for a user input but you can change it to fire the stop method from anywhere
public static void main(String[] args) {
List<MyClass> myThreads = new ArrayList<>();
for (int i = 0; i < 2; i++) {
MyClass myClass = new MyClass();
Thread t = new Thread(myClass);
t.start();
myThreads.add(myClass);
}
Scanner in = new Scanner(System.in);
in.next();
for(MyClass t : myThreads){
t.stop();
}
}
class MyClass implements Runnable {
private Boolean flag;
public MyClass() {
this.flag = true;
}
#Override
public void run() {
while (flag) { // <--- I do know that the "true" has to be changed to a Boolean
try {
System.out.println("Waiting 6 seconds!");
Thread.sleep(6 * 1000);
System.out.println("------------------------------------");
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println("Thread in program ended!");
}
public void stop(){
this.flag = false;
} }
The easy way would be to store all your threads in a set and make loop joining them at the end.
Be aware that this is not the most ortodox neither the most efficient way to do this.
In your main:
HashSet<Thread> threads = new HashSet();
for (int i = 0; i < 2; i++) {
Thread t = new Thread(new MyClass());
threads.add(t);
t.start();
}
for (Thread thread: threads) {
thread.join();
}
some more material
The following code uses an executor service to fix the number of threads that run at any time, it provides a Future object that also tells you when your thread has shutdown gracefully. They share a shutdown object as well. This offers you a bit more flexibility as the executor service can let you decide how many threads run at any one time gracefully.
First lets created a shared shutdown object that will notify all the threads it is time to shut down. There will be one instance of this and each thread will have a copy.
public static class Shutdown {
private boolean running;
public void shutdown() {
this.running = false;
}
public boolean isRunning() {
return running;
}
}
Next let me just create a dummy thread that does nothing more than sleep forever while it is running. Obviously you can simply replace this with your own thread to do something useful.
public static class MyClass implements Runnable {
final Shutdown shutdown;
public MyClass(Shutdown shutdown) {
this.shutdown = shutdown;
}
#Override
public void run() {
while (shutdown.isRunning()) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
System.out.println("Did not gracefully shut down");
}
}
System.out.println("Thread in program ended!");
}
}
}
Now for the main class which will run everything, this is where the magic happens.
public class Main {
public static void main(String[] args) {
//run exactly 10 threads at a time
ExecutorService executorService = Executors.newFixedThreadPool(10);
//this is how we shut it down
Shutdown globalShutdown = new Shutdown();
//start up the 10 threads
List<Future<?>> futures = new ArrayList<>();
for(int i = 0; i< 10; i++)
futures.add(executorService.submit(new MyClass(globalShutdown)));
//gracefully shut them down
globalShutdown.shutdown();
try {
//wait for them all to shutdown
for(Future<?> future : futures)
future.get();
} catch (InterruptedException e) {
throw new IllegalStateException("This should never happen");
} catch (ExecutionException e) {
throw new IllegalStateException("This should never happen");
}
//everything got shutdown!
}
in practice however you probably also want to handle the case where your thread may not end gracefully due to a bug. Rather than stall forever you might want to add a timeout and if that timeout is exceeded then simply forcibly terminate all remaining threads. To do that replace the above try-catch block with this.
try {
//wait for them all to shutdown
boolean timedout = false;
for(Future<?> future : futures) {
if( !timedout ) {
try {
future.get(30, TimeUnit.SECONDS);
} catch (TimeoutException e) {
timedout = true;
}
}
if(timedout) {
future.cancel(true);
}
}
} catch (InterruptedException | ExecutionException e) {
throw new IllegalStateException("This should never happen");
}
How much time does a Thread need to stop/disappear after its interrupt() method has been called?
Consider the following code:
public class MyThread {
public boolean flag = true;
public void run() {
while(flag) {
doSomething();
Thread.sleep(20);
}
}
}
void foo() {
MyThread t = new MyThread();
t.start();
Thread.sleep(100);
t.flag = false;
t.interrupt();
}
Does the assignment t.flag = false; have any effect? In other words, can a thread exit its run() method and terminate "normally" before it is interrupted?
similar question
For sharing data one needs volatile. Better would be to catch the InterruptedException.
public class MyThread {
public volatile boolean flag = true;
public void run() {
try {
while(flag) {
doSomething();
Thread.sleep(20);
}
} catch (InterruptedException ie) {
...
}
}
}
Check agains isInterrupted, anhd throw it again since when it returns true it consumes the message.
public class MyThread {
public void run() {
try {
while(!Thread.isInterrupted()) {
doSomething();
Thread.sleep(20);
}
} catch (InterruptedException ie) {
Thread.interrupt();
}
}
}
Making the flag unecessary.
If you want to use the flag and finish the code gracefully you don't need to use interrupt and catch the Exception.
I was reading this post and the suggestions given to interrupt one thread from another is
" " " Here are a couple of approaches that should work, if implemented correctly.
You could have both threads regularly check some common flag variable (e.g. call it stopNow), and arrange that both threads set it when they finish. (The flag variable needs to be volatile ... or properly synchronized.)
You could have both threads regularly call the Thread.isInterrupted() method to see if it has been interrupted. Then each thread needs to call Thread.interrupt() on the other one when it finishes." " "
I do not understand how the second approach is possible that is using Thread.isInterrupted().
That is, how can Thread-1 call Thread.interrupt() on Thread-2.
Consider this example, in the main method I start two threads t1 and t2. I want t1 to stop t2 after reaching certain condition. how can I achieve this?
class Thread1 extends Thread {
public void run(){
while (!isDone){
// do something
}
} //now interrupt Thread-2
}
class Thread2 extends Thread {
public void run(){
try {
while(!Thread.isInterupted()){
//do something;
}
catch (InterruptedExecption e){
//do something
}
}
}
public class test {
public static void main(String[] args){
try {
Thread1 t1 = new Thread1();
Thread2 t2 = new Thread2();
t1.start();
t2.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
The context of this is that you are trying to implement your scheme using thread interrupts.
In order for that to happen, the t1 object needs the reference to the t2 thread object, and then it simply calls t2.interrupt().
There are a variety of ways that t1 could get the reference to t2.
It could be passed as a constructor parameter. (You would need to instantiate Thread2 before Thread1 ...)
It could be set by calling a setter on Thread1.
It could be retrieved from a static variable or array, or a singleton "registry" object of some kind.
It could be found by enumerating all of the threads in the ThreadGroup looking for one that matches t2's name.
public class test {
private static boolean someCondition = true;
public static void main(String[]args){
Thread t2 = new Thread(new someOtherClass("Hello World"));
Thread t1 = new Thread(new someClass(t2));
t2.start();
t1.start();
try {
t1.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
static class someClass implements Runnable{
Thread stop;
public someClass(Thread toStop){
stop = toStop;
}
public void run(){
while(true){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(someCondition && !stop.isInterrupted()){
stop.interrupt();
}
}
}
}
static class someOtherClass implements Runnable{
String messageToPrint;
public someOtherClass(String s){
messageToPrint = s;
}
public void run(){
while(true){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(messageToPrint);
}
}
}
}
You could consider the use of Future interface. It provides a cancel() method.
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html
Playing with interruption makes your life unnecessarily hard. Besides the fact that your code must know the threads, interruption does not provide any context information about the reason of the interruption.
If you have a condition that is shared by your code possibly executed by different threads, just encapsulate that condition into an object and share that object:
public class Test {
public static void main(String[] args) {
Condition c=new Condition();
new Thread(new Setter(c)).start();
new Thread(new Getter(c, "getter 1")).start();
// you can simply extend it to more than one getter:
new Thread(new Getter(c, "getter 2")).start();
}
}
class Getter implements Runnable {
final Condition condition;
final String name;
Getter(Condition c, String n) { condition=c; name=n; }
public void run() {
while(!condition.isSatisfied()) {
System.out.println(name+" doing something else");
try { Thread.sleep(300); } catch(InterruptedException ex){}
}
System.out.println(name+" exiting");
}
}
class Setter implements Runnable {
final Condition condition;
Setter(Condition c) { condition=c; }
public void run() {
System.out.println("setter: doing my work");
try { Thread.sleep(3000); }
catch(InterruptedException ex){}
System.out.println("setting condition to satisfied");
condition.setSatisfied();
}
}
class Condition {
private volatile boolean satisfied;
public void setSatisfied() {
satisfied=true;
}
public boolean isSatisfied() {
return satisfied;
}
}
The big advantage of this encapsulation is that it is easy to extend. Suppose you want to allow a thread to wait for the condition instead of polling it. Taking the code above it’s easy:
class WaitableCondition extends Condition {
public synchronized boolean await() {
try {
while(!super.isSatisfied()) wait();
return true;
} catch(InterruptedException ex){ return false; }
}
public synchronized void setSatisfied() {
if(!isSatisfied()) {
super.setSatisfied();
notifyAll();
}
}
}
class Waiter implements Runnable {
final WaitableCondition condition;
final String name;
Waiter(WaitableCondition c, String n) { condition=c; name=n; }
public void run() {
System.out.println(name+": waiting for condition");
boolean b=condition.await();
System.out.println(name+": "+(b? "condition satisfied": "interrupted"));
}
}
Without changing the other classes you can now extend your test case:
public class Test {
public static void main(String[] args) {
WaitableCondition c=new WaitableCondition();
new Thread(new Setter(c)).start();
new Thread(new Getter(c, "getter 1")).start();
// you can simply extend it to more than one getter:
new Thread(new Getter(c, "getter 2")).start();
// and you can have waiters
new Thread(new Waiter(c, "waiter 1")).start();
new Thread(new Waiter(c, "waiter 2")).start();
}
}
hello guys this is my code , problem am facing is that despite calling notifyAll, it is not releasing the lock , can you please state the reason and tell the solution. Am new to threads. Thanks in advance.
class Lock1 {}
class Home1 implements Runnable {
private static int i = 0;
private Lock1 object;
private Thread th;
public Home1(Lock1 ob, String t) {
object = ob;
th = new Thread(this);
th.start();
}
public void run() {
synchronized (object) {
while (i != 10) {
++i;
System.out.println(i);
}
try {
// System.out.println("here");
object.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("here thread 1");
}
}
}
class Home2 implements Runnable {
private static int i = 0;
private Lock1 object;
Thread th;
public Home2(Lock1 ob, String t) {
object = ob;
th = new Thread(this);
th.start();
}
public void run() {
synchronized (object) {
while (i != 10) {
++i;
System.out.println(i);
}
try {
// System.out.println("here");
object.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("here thread 2");
}
}
}
public class Locking {
public static void main(String arg[]) {
Lock1 ob = new Lock1();
new Home1(ob, "thread 1");
new Home2(ob, "thread 2");
synchronized (ob) {
ob.notifyAll();
}
}
}
When you use notifyAll, you should also have a state changed and when you use wait, you should check that state change.
In your case it is likely that notifyAll will be called long before the threads really have time to start. (For a computer, starting a thread takes an eternity, like 10,000,000 clock cycles) This means the notifyAll is lost. (It only notifies threads which are actually waiting right at that moment)