Is it possible to call wait method for another thread rather than the current thread.what I am asking is something like this :
Code:
public class a extends JApplet{
JButton start= new JButton("Start");
JButton wait= new JButton("Wait");
JButton notify = new JButton("Notify");
final Thread bthread = new Thread(new B(), "BThread");
#Override
public void init(){
//start
this.getContentPane().setLayout(new FlowLayout());
start.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Started");
}
});
this.getContentPane().add(start);
//wait
wait.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Waited");
synchronized(bthread) //something like this
{
try {
bthread.wait(); //is it possible instead of the current thread the bthread get invoke
} catch (Exception ex) {
Logger.getLogger(a.class.getName()).log(Level.SEVERE, null, ex);
}}
}
});
this.getContentPane().add(wait);
//notify
notify.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Notified");
synchronized(a.this){
a.this.notify();
}}
});
this.getContentPane().add(notify);
}
class B implements Runnable
{
int i=0;
#Override
public void run() {
while(i<10){
System.out.println(" i = "+i);
// i++;
}
}
}
}
Is it possible that when wait button is clicked the bthread go into wait state?
do you want bthread to actually pause its execution, whatever it is doing? There's no way to do that, AFAIK. You may however set bthread polling on some shared stateful synchronization object (a CountDownLatch or a Semaphore for instance, look into the java.util.concurrent package), so that you alter the status of the object to set bthread waiting.
No. You can't suspend a thread like that.
But you can implement a wait method in the B class:
class B implements Runnable
{
private boolean wait = false;
public void pause() {
wait = true;
}
int i=0;
#Override
public void run() {
while(i<10){
if (wait) {
wait();
}
System.out.println(" i = "+i);
// i++;
}
}
}
I dont think so.
Thread B can check some variable, for example boolean pause; If its true it can wait. It needs to be volatile or needs synchronization and something to wake it up is needed, but that depends on what you want it to do.
But if thread B is doing some long operation, it can be running long time before it checks whether it should wait.
No, you can only control the current thread, if you wait on another thread you actually call wait() using that object (the thread you are referring to) as a monitor. So you either have to time out, or someone call interrupt on that object to make your current thread start again.
You have to build that logic into your program, causing it to wait after a variable or message be flagged. Another way would be using locks or semaphores.
You could also call interrupt on that thread if you want it to stop, but that logic must also be built into your program, as it might just throw an InterruptedException if the thread is doing IO.
Related
I am working on a Robotic Analog to digital button listener.
Where There is a synchronized (this) block when the action performed.
public void Init() {
new Timer(200, taskPerformer).start();
)
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent e) {
//not synchronized code
synchronized (this) {
//synchronized code
}
}
}
Now my question is How can I understand which Thread Failed to enter that block?
Is there any way so that I can handle those threads. Similar to the if-else , can I handle those thread who could not entered.
Edit: simply want to print("Could not Enter The Block"); How can I do that.?
Thanks.
you can lock on an Object (instead of this) which is shared across group of Threads where you need real synchronization
lock object
Object lockGroup1 = new Object();
Thread that holds it
class MyThread implements Runnable {
Object lock;
public MyThread(Object lock){
this.lock = lock;
}
// other stuff ofcourse
}
and
MyThread thread1 = new MyThread(lock1);
Updates based on Comments
Set<Long> waitingThreads = Collections.synchronizedSet(new HashSet<Long>());
public void myMethod() {
waitingThreads.add(Thread.currentThread().getId());
synchronized (this){
waitingThreads.remove(Thread.currentThread().getId());
}
}
I want to have a class that starts a Thread and provides methods to pause and continue this Thread. My first approach was to have flag, which loops a sleep method as long as the value is true. Something like :
public class Bot {
private Thread t ;
private boolean isPaused;
public Bot(){
t = new Thread(new Runnable(){
#Override
public void run() {
while (true) {
System.out.println("Hi");
while(isPaused){
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
});
t.start();
}
public void pauseBot(){
isPaused = true;
}
public void continueBot(){
isPaused = false;
}
}
But since the Thread is still running and wasting CPU, I dont find this to be a good solution. How would this look with wait() and notify().
I had a look at various tutorials about that topic but somehow I couldnt apply them to my issue.
Everytime I tried it I either got IllegalMonitorStateException or the code stopped my whole application and not just the Thread I wanted to be stopped.
Another question I have is: How do prevent the Thread from beeing paused at a critical moment e.g.
Runnable r = new Runnable(){
#Override
public void run() {
while(true){
task1();
task2();
//Thread mustn't be stopped from here....
task3();
task4();
task5();
task6();
task7();
//... to here
task8();
task9();
task10();
}
}
};
Because when task3() .... task7() deal with something that would expire while the Thread is paused there must be a way to let the Thread finish task7() until it pauses.
I hope you can help me with my issue.
Thanks in advance,
Flo
So given this is your Thread class:
public class MyThread extends Thread
{
First, you need an lock object. This object can be everything, and if you use an existing object this takes less memory. Also define a flag if the bot should be paused.
public Object lock = this;
public boolean pause = false;
Now, define a pause() and continue() method for the thread. This sets the pause flag.
public void pause ()
{
pause = true;
}
public void continue ()
{
pause = false;
Here you need to wake up the thread. Note the synchronized on the lock object so that you don't get an IllegalMonitorStateException.
synchronized (lock)
{
lock.notifyAll();
}
}
No, define a method that automatically pauses the thread when it should be paused. You might call this at every moment when the thread can be paused.
private void pauseThread ()
{
synchronized (lock)
{
if (pause)
lock.wait(); // Note that this can cause an InterruptedException
}
}
Now, you can define your thread in the run() method:
public void run ()
{
task1();
task2();
pauseThread();
task3();
task4();
task5();
task6();
task7();
pauseThread();
task8();
task9();
task10();
}
}
Could someone please tell me how to stop a thread if I have the following structure?
I want to stop the thread B after it expires thread C.
c = new c();
c.start();
b = new b();
b.start();
class c extends Thread {
#Override
public void run() {
// DRAW IMAGE
// b.stop(); - doenst work
}
}
class b extends Thread {
#Override
public void run() {
// PROGRESS BAR
}
}
There is no good way to stop a thread instantly.
There is Thread.stop(), but it is dangerous and deprecated. Don't use it unless you have thoroughly analyzed your code and determined that the risks are acceptable.
There is Thread.interrupt(), but there is no guarantee that the thread will stop quickly, or even stop at all.
For Example:
while (!Thread.interrupted()) {
try {
//do stuff
} catch (InterruptedException e) {
// end up
}
}
There is the approach of writing the thread to periodically check a flag, but if the flag is not checked frequently (by accident or by design), then the thread won't stop quickly.
Please Refer to this for more details
Don't use .stop() use interrupt() instead
You need to check periodically in your b thread if it gets interrupted, if interrupted , you can take proper actions -
if(b.isInterrupted()){
//end your work
}
---> http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html
Don't use Thread.stop() method, It's already deprecated, in this case you can handle the stopping of the b thread in your code.
For example:
class b extends Thread {
private volatile boolean stopped = false;
public void stop () {
stopped = true;
}
#Override
public void run() {
// PROGRESS BAR
while ( ! stopped ) {
// paint the progress bar
}
}
}
You might want to take a look at this. You can use a flag or just use Thread.currentThread().interrupt(), you can check if a thread is interrupted by calling Thread.isInterrupted() on it.
The solution to this is explained quite well here. Any thread that might need a status flag for shutdown could have the following structure:
volatile boolean shutdownRequested;
...
public void shutdown() { shutdownRequested = true; }
public void doWork() {
while (!shutdownRequested) {
// do stuff
}
}
Thus, in your case, your class B would look similar to the above. And then, in class C, you can call the shutdown() method of class B.
create a lockable object in your calling code
Boolean canRun = true;
c = new c();
when b has finished set canRun to false
periodically check value of canRun in c
Well, try this :
while(true) {
if (!c.isAlive() && b.isAlive()){
b.interrupt();
}
}
Try something like
private void startActionPerformed(java.awt.event.ActionEvent evt) {
p=new Progress();
myThread=new Thread(p);
p.setLocationRelativeTo(null);
p.setVisible(true);
myThread.start();
}
private void stopActionPerformed(java.awt.event.ActionEvent evt) {
if(myThread!=null){
p.Terminate();
try {
myThread.join();
} catch (InterruptedException ex) {
Logger.getLogger(ClassA.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
////////////////////////////////////////////////////////////////
How it Works and Stopped!
int i;
volatile boolean running=true;
public void run(){
while(running){
for(i=0;i<=100;i++){
pro.setValue(i);
try {
Thread.sleep(200);
} catch (InterruptedException ex) {
Logger.getLogger(Progress.class.getName()).log(Level.SEVERE, null, ex);
return;
}
if(i==100){
Terminate();
break;
}
}
}
}
public void Terminate(){
running=false;
}
/////////////////////////////////////////////////////////////////////
Use a Boolean flag.
For Thread safety, use AtomicBoolean.
AtomicBoolean running = new AtomicBoolean(Boolean.TRUE);
In your run() method check this flag in a while condition:
public void run(){
while(running){
...
}
}
When you want to stop this Thread, change the running to false
I want to pause and start thread untill variable standby.
But wait() and notify() is not work for me.
Is this a collect way to pause thread?
private boolean _threadIsWaiting = true;
private Object _specialObjectFromHttp;
public void methodToUse() {
Thread thread = new Thread(new Runnable() {
getParamsFromHttp();
while (_threadIsWaiting) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
convertObject(_specialObjectFromHttp);
)};
}
// Callback method (Thread wait for this.)
private void getParamsFromHttpCallBack(Object result) {
_specialObjectFromHttp = result;
_threadIsWaiting = false;
}
You could use an object to wait on, and call notify on it. I believe that to be the better approach (Actually, it is almost always better to utilize such a mechanism instead of sleeping and bool checking).
private Object _specialObjectFromHttp;
public void methodToUse() {
Thread thread = new Thread(new Runnable() {
getParamsFromHttp();
_specialObjectFromHttp.wait();
)};
}
// Callback method (Thread wait for this.)
private void getParamsFromHttpCallBack(Object result) {
_specialObjectFromHttp = result;
_specialObjectFromHttp.notifyAll();
}
In this case it seems plausible to just use the object that is being used in that control flow anyways, but you could also just add another object that has no purpose other than being waited for.
You could use a SynchronousQueue this will block until the information you need is provided. So in one thread call take, this will wait for a put on a different thread.
Both methods are blocking and no manual syncing is needed.
Is there a way to wait for all Runnables submitted to the SWT UI Thread via asyncExec(...) to finish?
Background:
I have a long-running operation, which among other things is triggering events that in turn submit Runnables to the SWT UI thread via the asyncExec(...) instance method of Display.
The progress of the long-running operation is shown in a ProgressMonitorDialog, and I would like to close the dialog only after the UI thread has finished executing the Runnables.
Changing the calls from asyncExec(...) to syncExec(...) is not an option, as the latter is not desired when the events are triggered from other contexts.
org.eclipse.swt.widgets.Display.readAndDispatch() will process an event from the event queue and return false if there are no more events to process. But you probably don't want to use this as it processes an event.
asyncExec(*) is a FIFO queue (although OS graphics events supersede the asyncExecs), so you could do most of your long-running op processing and then place a final asyncExec in the queue:
final boolean[] done = new boolean[1];
Runnable r = new Runnable() {
public void run() {
done[0] = true;
}
};
// now wait for the event somehow. The brute force method:
while (!done[0]) {
Thread.sleep(200);
}
In theory, all of the other asyncExecs spawned from your long running op will be finished by the time you get to the last one.
EDIT: potential other option
Create your own org.eclipse.core.runtime.jobs.Job and then join() it at the end:
public static class RefCountJob extends Job {
public RefCountJob() {
super("REF_COUNT");
}
int count = 0;
public void increment() {
count++;
}
public void decrement() {
count--;
}
#Override
protected IStatus run(IProgressMonitor monitor) {
monitor.beginTask("WAITING", IProgressMonitor.UNKNOWN);
while (count > 0) {
Thread.sleep(200);
monitor.worked(1);
}
monitor.done();
return Status.OK_STATUS;
}
}
To use it, increment() it every time you are going to fire off events, and have them decrement it when they're done (You have to make sure they decrement it no matter what exception is thrown :-)
RefCountJob ref = new RefCountJob();
// ... do stuff, everybody increments and decrements ref
ref.increment();
// ... do more stuff
ref.increment();
// at the end of your long-running job
ref.schedule();
ref.join();
Thanks, I ended up with the following. I think it is a pretty clean solution. By the way I would upvote your answer if I had enough reputation for that :)
public class SWTThreadingUtils
{
public static void waitForAsyncExecsToFinish(Display display)
{
Object waitObj = new Object();
display.asyncExec(new DummyRunnable(waitObj));
synchronized (waitObj)
{
try {
waitObj.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
private static class DummyRunnable implements Runnable
{
private Object waitObj;
public DummyRunnable(Object waitObj)
{
this.waitObj = waitObj;
}
#Override
public void run()
{
synchronized (waitObj)
{
waitObj.notify();
}
}
}
}