I have been using quite some SwingWorkers recently, and had some issues so I tried to create an SCSSE, but that apparently doesn't want to work
static SwingWorker worker;
public static void main(String[] args) {
worker = new SwingWorker<Object, Object>() {
protected Object doInBackground() throws Exception {
return "Hello";
}
protected void done() {
System.out.println("I'm done!");
};
};
System.out.println("working");
try {
System.out.println("result: " + worker.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
System.out.println("working finished");
}
when this is executed, it prints "working" and then the script continues to run indefinitely...
You never start the SwingWorker, so the worker.get() method is blocking while it waits for the worker to complete.
You can verify this by adding:
System.out.println("waiting for result");
System.out.println("result: " + worker.get());
If you want the SwingWorker to execute then you need to invoke:
worker.execute()
after you create the SwingWorker.
Related
ScheduledExecutorService is still running after calling its shutdown methos from class's shutdown method below.
I was not expecting to see perioudRun's call after shutdown
Running the method shutdown
Running the method periodicRun-
What should I do ensure, the schedule run is cancelled ?
class test {
private final ScheduledExecutorService scheduler =
Executors.newScheduledThreadPool(1);
test() {
scheduler.scheduleWithFixedDelay(new Runnable() {
#Override
public void run() {
funcA("periodicRun-");
}
}, 15, 15, TimeUnit.SECONDS);
}
private void funcA(String path) {
LOGGER.info("Running the method " + path)
}
public void shutdown() {
long startTimeMs = System.currentTimeMillis();
scheduler.shutdown(); // Disable new tasks from being submitted
try {
// Wait a while for existing tasks to terminate
if (!scheduler.awaitTermination(initialTerminationSeconds, TimeUnit.SECONDS)) {
scheduler.shutdownNow(); // Cancel currently executing tasks
// Wait a while for tasks to respond to being cancelled
scheduler.awaitTermination(retryTerminationSeconds,
}
} catch (InterruptedException ie) {
// (Re-)Cancel if current thread also interrupted
scheduler.shutdownNow();
// Preserve interrupt status
Thread.currentThread().interrupt();
}
}
funcA("shutdown-");
}
}```
The code you provided does not compile. I made some corrections and some assumptions where it did not compile, and the following code works as expected, i.e. "periodicRun" is not printed after shutdown() is called:
class Test {
public static void main(String[] args) {
Test test = new Test();
test.test(); // CALL TEST METHOD
Thread t = new Thread(() -> {
try {
Thread.sleep(2500);
} catch (InterruptedException e) {
e.printStackTrace();
}
test.shutdown(); // CALL SHUTDOWN METHOD
});
t.start();
}
private final int initialTerminationSeconds = 1;
private final int retryTerminationSeconds = 1;
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
void test() {
scheduler.scheduleWithFixedDelay(new Runnable() {
#Override
public void run() {
funcA("periodicRun-");
}
}, 15, 15, TimeUnit.SECONDS);
}
private void funcA(String path) {
System.out.println("Running the method " + path);
}
public void shutdown() {
long startTimeMs = System.currentTimeMillis();
scheduler.shutdown(); // Disable new tasks from being submitted
try {
// Wait a while for existing tasks to terminate
if (!scheduler.awaitTermination(initialTerminationSeconds, TimeUnit.SECONDS)) {
scheduler.shutdownNow(); // Cancel currently executing tasks
// Wait a while for tasks to respond to being cancelled
scheduler.awaitTermination(retryTerminationSeconds, TimeUnit.SECONDS);
}
} catch (InterruptedException ie) {
// (Re-)Cancel if current thread also interrupted
scheduler.shutdownNow();
// Preserve interrupt status
Thread.currentThread().interrupt();
}
funcA("shutdown-");
}
}
As this code works as expected, the problem in your code is either somewhere else or the assumptions and corrections I made to your code are incorrect.
I am new to working with ExecutorService, Future, and Runnable in java to set up timeouts on threads. I am working on a program where my main thread will call another thread to parse an XML file and (for security purposes) time out after a certain amount of time. I have been googling for hours and read many StackOverFlow threads and I just cannot seem to get the main thread to interrupt the secondary thread at all. When I run this program, the xml parser will go on forever parsing ridiculously large files, and I cannot seem to get it to be interrupted. Any help would be greatly appreciated. My code for both threads is below.
public class xmlParser{
private static class Parse implements Runnable {
private final String xmlFile;
public Parse(String xmlFile) {
this.xmlFile = xmlFile;
}
#Override
public void run() {
try {
while (!Thread.interrupted()) {
XMLReader xmlReader = XMLReaderFactory.createXMLReader();
xmlReader.setContentHandler(new MyContentHandler());
xmlReader.parse(new InputSource(xmlFile));
}
}
catch (Exception e) {
System.err.println("TIMEOUT ERROR: Took too long to parse xml file.");
e.printStackTrace();
}
}
}
public static void main(String[] args) throws InterruptedException {
ExecutorService executor = Executors.newSingleThreadExecutor();
Future future = executor.submit(new Parse(args[0]));
try {
future.get(1, TimeUnit.SECONDS);
}
catch (Exception e) {
future.cancel(true);
}
finally {
executor.shutdownNow();
}
}
}
Note: I am aware of the multiple types of exceptions that future.get(long timeout, TimeUnit unit) will throw and will handle that later. Currently, I simply want my main thread to interrupt the Parse thread after 1 second of running.
I tried to reproduce with a simpler job:
static class FiveSecJob implements Callable<String> {
#Override
public String call() {
long t0 = System.currentTimeMillis();
try {
Thread.sleep(5000);
return "success";
} catch (Exception e) {
System.out.println("interrupted after " + (System.currentTimeMillis() - t0) / 1000d + "s: " + e);
return e.getMessage();
}
}
}
#Test
public void testTimeout() {
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(new FiveSecJob());
String s = "initial value";
try {
s = future.get(1, TimeUnit.SECONDS);
} catch (Exception e) {
System.out.println("cancelling future (" + e + ")");
future.cancel(true);
} finally {
executor.shutdownNow();
}
System.out.println("s: " + s);
}
It seems to cancel the job like intendend. The output is:
cancelling future (java.util.concurrent.TimeoutException)
s: initial value
interrupted after 1.0s: java.lang.InterruptedException: sleep interrupted
I am trying to signal between two threads using the below FutureResult class which extends FutureTask class. When run the script, it prints the following result.
SENDING: 0
SENT: 0
POLL: FutureResult#513431
SIGNALLED: FutureResult#513431
Then the program hang up forever. I expect FutureResult instance should return the value from it's blocking get method. Then print the result in the console. But FutureResult.get is blocking forever.
import java.util.concurrent.*;
/**
* Created by someone on 20/08/2015.
*/
final public class FutureResult<T> extends FutureTask<T> {
private static final Object SS = "SS";
public FutureResult() {
super(() -> null);
}
public void signal(final T value) {
set(value);
}
public void signalError(final Throwable throwable) {
setException(throwable);
}
public static void main(String... args) throws Exception {
final ArrayBlockingQueue<FutureResult> queue = new ArrayBlockingQueue<>(1000000);
new Thread(() -> {
while (true) {
try {
final FutureResult poll = queue.take();
System.out.println("POLL: " + poll);
if (poll != null) {
poll.signal(SS);
System.out.println("SIGNALLED: " + poll);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
new Thread(() -> {
for (int i = 0; i < 1; i++) {
final FutureResult<Object> result = new FutureResult<>();
System.out.println("SENDING: " + i);
queue.offer(new FutureResult());
try {
System.out.println("SENT: " + i);
result.get();
System.out.println("GOT : " + i);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}).start();
}
}
This is the problem:
queue.offer(new FutureResult());
You're setting the value on one FutureResult, but that's not the one you're waiting for. Just change that line to:
queue.offer(result);
and it works fine.
Looks like the confusion is in the use of FutureTask. FutureTask is designed as a Runnable; running it is necessary.
Honestly, based on the code, it looks like the custom code is implementing something similar to FutureTask. If the intent here is to learn to use FutureTask, then create a FutureTask instance with a "run" method, and then execute that run method. On completion of the run method, the FutureTask.get() will complete.
I want to create long-running application for performing various tasks on different threads. Each task should have one-minute timeout. Here is my implementation:
runner = new Thread(new Runnable() {
#Override
public void run() { }
// some actions here
});
runner.start();
startJoin = System.currentTimeMillis();
runner.join(TIMEOUT);
stopJoin = System.currentTimeMillis();
if ((stopJoin - startJoin) >= TIMEOUT)
throw new TimeoutException("Timeout when reading the response from process");
In general case it is working and throwing TimeoutExceptions, but sometimes it is doing nothing after even few hours. So the questions is if Thread.join is reliable on Android?
I have an idea to use Thread.wait and notify instead of that, what is the better way in your opinion?
Refer below program.
public static void main(String[] args) throws InterruptedException {
long TIMEOUT=100;
Thread runner = new Thread(new Runnable() {
#Override
public void run() {
for(;;){
System.out.println("running ");
}
}
// some actions here
});
runner.start();
long startJoin = System.currentTimeMillis();
runner.join(TIMEOUT);
long stopJoin = System.currentTimeMillis();
if ((stopJoin - startJoin) >= TIMEOUT)
try {
throw new Exception("Timeout when reading the response from process");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Running Thread");
}
This program never ends that means your logic is incorrect.
Better to use TimerTask.
I prefer doing all time base task using Timer and TimerTask. Check the following code and probably this should be useful to you:
Timer t =new Timer();
t.schedule(new TimerTask() {
#Override
public void run() {
//The task you want to perform after the timeout period
}
}, TIMEOUT);
EDIT
I am giving a try at solving your problem. I am using the code written by #amicngh as my base code and have done some modifications to it. I presume that after the TIMEOUT period you want to close the running thread. Check the following code runs fine and the explanation that follows:
public class ThreadTest {
public static void main(String[] args) throws InterruptedException {
final long TIMEOUT=100;
final long startJoin = System.currentTimeMillis();
Thread runner = new Thread(new Runnable() {
long stopJoin;
#Override
public void run() {
try{
for(;;){
System.out.println("running ");
stopJoin = System.currentTimeMillis();
if ((stopJoin - startJoin) >= TIMEOUT){
throw new Exception();
}
}
}
catch (Exception e) {
// TODO: handle exception
}
}
// some actions here
});
runner.start();
synchronized (ThreadTest.class) {
ThreadTest.class.wait(TIMEOUT);
}
/*if ((stopJoin - startJoin) >= TIMEOUT)
try {
throw new Exception("Timeout when reading the response from process");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
System.out.println("Running Thread");
}
}
The Thread API description says that it is unsafe to destroy or stop (hence both these method has been deprecated) and one of the way to stop a thread is to throw an exception. Hence I am checking for the Timeout inside the runner thread. Now about making the Main thread wait it is done by the 2 lines of code which uses synchronized to synchronize the access to the thread.
Hope this code and explanation solves your problem.
I believe that the main thread cannot die before the child thread. But is there any way to check that ? I wrote a simple program below. Can anyone prove it practically leaving theory aside ?
class childre extends Thread
{
public void run()
{
for( int i=0 ; i<10 ;i++)
{
System.out.println( " child " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public class ChildThreadb4main
{
/**
* #param args
*/
public static void main(String[] args)
{
// TODO Auto-generated method stub
System.out.println("main");
childre c1 = new childre();
c1.start();
for(int i=0;i<5;i++)
{
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println( " child thread alive ? " + c1.isAlive());
}
}
After suggestion from James. I tried the following program.
public class MainChildDie {
public static void main(String ar[]){
final Thread mainThread = Thread.currentThread();
System.out.println("main run ");
new Thread(){
public void run(){
Thread childThread= Thread.currentThread();
for(int i=0; i<10;i++){
System.out.println( "child"+i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("main alive " + mainThread.isAlive());
}
}.start();
}
}
From http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html :
The Java Virtual Machine continues to execute threads until either of
the following occurs:
The exit method of class Runtime has been called and the security
manager has permitted the exit operation to take place.
All threads
that are not daemon threads have died, either by returning from the
call to the run method or by throwing an exception that propagates
beyond the run method.
In your case, when the main thread dies, the JVM does not exit, because you still have the created threads running, and they're daemon by default, because of this:
The newly created thread is initially marked as being a daemon thread if and only if the thread creating it is currently marked as a daemon thread. The method setDaemon may be used to change whether or not a thread is a daemon.
Cite: http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html#setDaemon(boolean)
While the code is executing, take a Full Thread dump and see what all Threads are active.
class AnotherClass {
public static void main(String arrp[]) throws Exception {
Thread t = new Thread() {
public void run() {
while (true) {
// do nothing
}
}
};
t.start();
//Sleep for 15 seconds
Thread.sleep(15000);
}
}
Compile and Execute it:
$ javac AnotherClass.java
$ java AnotherClass
Find the process:
$ ps -ef | grep AnotherClass
nikunj <<10720>> 10681 2 12:01:02 pts/9 0:04 java AnotherClass
nikunj 10722 10693 0 12:01:05 pts/6 0:00 grep Another
Take the Thread dump:
$ kill -3 <<10720>>
Output (excerpts):
"main" prio=10 tid=0x00039330 nid=0x1 waiting on condition [0xffbfe000..0xffbfe2a8]
at java.lang.Thread.sleep(Native Method)
at AnotherClass.main(AnotherClass.java:12)
"Thread-0" prio=10 tid=0x00a1b770 nid=0x12 runnable [0xadc7f000..0xadc7f970]
at AnotherClass$1.run(AnotherClass.java:7)
Take Another Thread dump (after 15 seconds):
$ kill -3 <<10720>>
New Output (excerpts):
"Thread-0" prio=10 tid=0x00a1b770 nid=0x12 runnable [0xadc7f000..0xadc7f970]
at AnotherClass$1.run(AnotherClass.java:7)
Conclusion:
main is gone.
Thread.currentThread().getThreadGroup().activeCount()
will return the active threads of a threadgroup of current thread default main
class childre extends Thread
{
public void run()
{
for( int i=0 ; i<10 ;i++)
{
System.out.println( " child " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getThreadGroup().activeCount());
}
}
You can use 'join' method to make sure that main thread waits till the child thread is completed.
childre c1 = new childre();
c1.start();
try {
c1.join();
} catch (InterruptedException exception) {
exception.printStackTrace();
}
class Print implements Runnable
{
Thread thread, mainThread;
Print(Thread t)
{
mainThread = t;
thread = new Thread(this, "Thread");
thread.start();
}
#Override
public void run()
{
for(int i = 0; i < 5; i++)
{
System.out.println(thread.getName() + "\t" + (i+1));
try
{
Thread.sleep(1000);
}
catch(InterruptedException ie)
{
System.out.println("Interrupted Exception " + thread.getName());
}
System.out.println("Is main thread alive "+mainThread.isAlive());
}
}
}
public class ThreadOne
{
public static void main(String[] args)
{
Print p1 = new Print(Thread.currentThread());
System.out.println("Main Thread Ends");
}
}
The above code will show you that the main thread has completed execution while the newThread spawned still running.