• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

How to obtain one Thread inside another Thread?

 
Ranch Hand
Posts: 514
1
Eclipse IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello!

I have two threads. One is SwingWorker(RunnableFuture). Another is my thread that extends java.lang.Thread.

My thread every second checks if user clicked that Cancel button or not.
If user clicked then I must somehow interrupt or stop or kill SwingWorker thread.

The problem that inside my Thread I cannot access SwingWorker thread.
I tried to pass reference of SwingWorker to my thread but this does not work. Because I cannot access methods of SwingWorker thread other than by calling
Thread.currentThread(). But if I call this using reference to SwingWorker within my thread it always returns my Thread but not SwingWorker.

How can I access SwingWorker(RunnableFuture) thread inside my own thread?

Thank you!

 
Bartender
Posts: 4179
22
IntelliJ IDE Python Java
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You need to obtain a reference to the same SwingWorker you use for the processing and use it to pass the cancel command. I would not attempt to access the underlying Thread (there is no reason to. And no, calling stop() is not a reason, it is deprecated and if you do use it could cause issues. See the Thread#stop() API). Fortunately, SwingWorker has a canel(boolean withInterrupt) method which does the job well.

You will also need to program the task you run inside the SwingWorker to pay attention to the cancel command. It should:
1) catch InterruptedExceptions, then check the SwingWorker's isCanceled() method. If true, treat the combined signal as a force stop.
2) regularly and preemptively check the SwingWorker's isCanceled() method to see if the thread was canceled, and end gracefully if it was. This is especially important if you don't do things that can be interrupted.
 
Bin Smith
Ranch Hand
Posts: 514
1
Eclipse IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello!

In one tutorial on javacreed I found how to do that. But cancel method of SwingWorker does not stop SwingWorker.
Instead I must modify method executed in doInBackground to check if current thread was interrupted Thread.currentThread().isInterrupted().
But this makes very hard for me to make my swingworker applicable for many different methods which I want to achieve.
Because I need to modify every method which is executed in doInBackground to include that check if SwingWorker is interrupted or not.

That's why I created new thread to run every second to check if SwingWorker was interrupted by cancel(true) and if so I would need somehow to tell SwingWorker to really cancel. After I call cancel(true) method on SwingWorker then nothing happens and code inside doInBackground is still executing unless I check if it was interrupted and throw new exception if so.

Probably what I want is not possible...
 
Steve Luke
Bartender
Posts: 4179
22
IntelliJ IDE Python Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It is not possible to do it safely (it is possible to do unsafely, but I won't perpetuate the problem). You are better off just checking the isCanceled() and/or isInterrupted() flags inside the task. Do so at key points (part of loop conditions, after writing data to a stream) and periodically if you have non-repeating task. Make sure that whenever you get the signal that all your resources get closed (streams flushed and closed, DB or network connections closed, anything which might hold memory cleaned, closed, or whatever the protocol is for cleanup).

That is the main problem with using Thread#stop(). If it works, then all the resources you use in the Thread are left in bad states, and that can cause issues that are impossible to fix.
 
Bin Smith
Ranch Hand
Posts: 514
1
Eclipse IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Furthermore, the most expensive for me is not my code but jdbc code. This is where I have a 1 - 2 seconds delay.
I cannot modify jdbc code. And if for user delay is bigger, user might click Cancel button forever
and I will interrupt only after the most expensive job is done and my little code for milliseconds to process ResultSet is left to execute.

But if I could access SwingWorker thread from my own thread I would say if after 3 seconds SwingWorker is not finished then stop it .
 
Steve Luke
Bartender
Posts: 4179
22
IntelliJ IDE Python Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Volodymyr Levytskyi wrote:Furthermore, the most expensive for me is not my code but jdbc code.


Ahh, but there is the rub, and part of the problem! A simple stop() might kill the thread, but what happens to the JDBC connection? What happens to the data in transfer? It would cause the database to go into an inconsistent state, and could, if the transaction had an insert or update involved, cause the DB to get into a bad state with bad data. It is precisely why you should not use a force-stop approach.

There are ways to get at this, though. For example, you could provide a method which cancels more aggressively. It calls the normal SwingWorker#cancel(true) but then also uses the SQL Statement's cancel() method to stop it from executing. This would cause a SQLException in the running code (stopping the long task) and provides the opportunity to rollback(). You would put this cancelAggressively() method inside the class which holds the long running task so that it can get access to the Statement that was used to execute the JDBC command.
 
Ranch Hand
Posts: 172
Redhat Ruby C++
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
AFAIK, in swing it isn't expected to control the threads directly (you usually leaves that task to the container). I think there might be some other way (like observer pattern).
 
Steve Luke
Bartender
Posts: 4179
22
IntelliJ IDE Python Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Luan Cestari wrote:AFAIK, in swing it isn't expected to control the threads directly (you usually leaves that task to the container).



What container? Swing is just a GUI library, it has no special 'container.' You manage threads in it the same way you manage threads in any desktop app, manually. The only difference is that you are sure there is an event dispatch thread and you have to be careful what data is accessed in the EDT, what data is accessed outside the EDT, and how long a task runs when run in the EDT. Then again, these are the same concerns you have with any multi-threaded situation in Java.

I think there might be some other way (like observer pattern).


Observer pattern is nice for observing data between threads. Can you expound on how you might use that to manage threads?
 
Luan Cestari
Ranch Hand
Posts: 172
Redhat Ruby C++
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Sorry, I misunderstood (I thought he wanted to kill EDT). If he have the reference of SwingWorker [1], he could call the cancel method [2] right?

[1] http://docs.oracle.com/javase/7/docs/api/javax/swing/SwingWorker.html
[2] http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/javax/swing/SwingWorker.java#543
 
Steve Luke
Bartender
Posts: 4179
22
IntelliJ IDE Python Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Luan Cestari wrote:Sorry, I misunderstood (I thought he wanted to kill EDT). If he have the reference of SwingWorker [1], he could call the cancel method [2] right?


Yes, as I mentioned in my first response and the OP acknowledged he knew in his second post. Did you see why he didn't think that was the solution? (in fact, it is the solution, just not by itself).
 
Luan Cestari
Ranch Hand
Posts: 172
Redhat Ruby C++
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Steve Luke wrote:

Luan Cestari wrote:Sorry, I misunderstood (I thought he wanted to kill EDT). If he have the reference of SwingWorker [1], he could call the cancel method [2] right?


Yes, as I mentioned in my first response and the OP acknowledged he knew in his second post. Did you see why he didn't think that was the solution? (in fact, it is the solution, just not by itself).



I don't know =/ I think he is a bit confused, maybe he could paste a simplified model of his code in github and show us what he really have there (like just some classes to reproduce his scenario to we see).

Regards!! =)

Luan
 
Steve Luke
Bartender
Posts: 4179
22
IntelliJ IDE Python Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Luan Cestari wrote:I don't know =/ I think he is a bit confused,


No, he is quite right, it can't be used by itself to get what he wants. It should be the mechanism he uses to trigger the cancel, though.
 
I think I'll just lie down here for a second. And ponder this tiny ad:
a bit of art, as a gift, the permaculture playing cards
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic