Stop TimerTask inside Runnable - java

I have stuck and don't know how to stop 2 Timer in my program. I have one Thread which is initialize the connection with a socket, then I have two Runnables which one is for the InputStream and one for OutputStream Here is my code:
public class Receiver extends Thread {
public void run() {
initializeThreads();
}
public static void initializeThreads() {
try {
// create new thread pool with four threads
application = Executors.newCachedThreadPool();
// create ArrayBlockQueueSync to store ints
Buffer sharedLocation = new ArrayBlockQueueSync();
// execute tasks
application.submit(new Reader(client.getInputStream(), sharedLocation));
application.submit(new Writer(client.getOutputStream(), sharedLocation));
application.submit(new MyTimer1(sharedLocation));
application.submit(new MyTimer2(sharedLocation));
} catch (IOException e) {
WriteExceptions.writeToFile(e);
System.err.println("Error on the run Receiver.\n" + e);
}
}
public static void disconnect() {
try {
client.close();
System.out.println("Close Socket");
shutdownAndAwaitTermination();
} catch (IOException e) {
e.printStackTrace();
WriteExceptions.writeToFile(e);
}
}
// This I found on the javadoc
public static void shutdownAndAwaitTermination() {
application.shutdown(); // Disable new tasks from being submitted
try {
// Wait a while for existing tasks to terminate
if (!application.awaitTermination(60, TimeUnit.SECONDS)) {
application.shutdownNow(); // Cancel currently executing tasks
// Wait a while for tasks to respond to being cancelled
if (!application.awaitTermination(60, TimeUnit.SECONDS))
System.err.println("Pool did not terminate");
}
} catch (InterruptedException ie) {
WriteExceptions.writeToFile(ie);
// (Re-)Cancel if current thread also interrupted
application.shutdownNow();
// Preserve interrupt status
Thread.currentThread().interrupt();
}
}
}
The Writer and Reader is like the follow:
public class Writer implements Runnable {
#Override
public void run() {
try {
while (!Thread.interrupted()) {
// read or write the socket
}
}
}
And the Timers like this:
public class Timer1 implements Runnable {
#Override
public void run() {
try {
// Declare the timer
Timer t = new Timer();
// Set the schedule function and rate
t.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
// perform my task
} catch (InterruptedException e) {
WriteExceptions.writeToFile(e);
}
}
},5 * 60 * 1000,24 * 60 * 60 * 1000);
} catch (Exception ex) {
WriteExceptions.writeToFile(ex);
}
}
}
My problem, the timer is not stop, when I call the disconnect method of the Receiver.Thanks

Thanks to the #fge suggestion, I use ScheduledExecutorService class and work fine.

Related

Thread.join() not behaving as expected

I'm pretty new to Multithreading in java but am totally stumped about why this isn't behaving as I want it to.
I have a Producer-Consumer wherein I have
private void produceConsume() {
try {
Thread producer = new Thread(new Runnable() {
public void run() {
try {
produce();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
completedProduce = true;
}
}
private void produce() throws InterruptedException {
synchronized (this) {
while (queue.size() == capacity) {
wait();
}
try(InputStream is = new FileInputStream(file)) {
queue.add("hello");
} catch (IOException e) {
LOG.error("Error doing stream stuff: " + e.getMessage(), e);
}
notify();
}
}
});
producer.start();
List<Thread> consumers = new ArrayList<>();
for (int i = 0; i < noOfThreads; i++) {
Thread consumer = new Thread(new Runnable() {
#Override
public void run() {
try {
consume();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void consume() throws InterruptedException {
while (queue.size() > 0 || !completedProduce) {
synchronized (this) {
while (queue.size() == 0 && !completedProduce) {
wait();
}
String s = queue.poll();
System.out.println(s);
}
notify();
}
}
}
});
consumer.start();
consumers.add(consumer);
}
for (Thread t : consumers) {
t.join();
}
producer.join();
} catch (Exception e) {
LOG.error("InterruptedException e: " + e.getMessage(), e);
} finally {
LOG.info("We are done with this file!");
}
}
Now, I've noticed that all functionality changes based on where I put my producer.join() statement. For example, if I put producer.join() right after producer.start() then everything works - but the number of threads has no impact on runtime. This makes sense as I'm slowed down drastically by how long it takes to produce and so the longest task wins out.
However, if I put producer.join() where it is in the example provided (I do the join when I do the join for the consumers) then everything just stops running before the producer actually finishes. As in, the program stalls after the first thing is consumed, waiting for something, but the thread never dies.
How do I make it so that things run correctly and nothing stalls waiting for another process to finish?
Thanks in advance,

ExecutorService timeout is not working as expected

The timeout should happen after one second, but it's not happening that way.
public class Worker implements Runnable {
int workerId;
public Worker(int workerId) {
super();
this.workerId = workerId;
}
public void run() {
System.out.println(workerId+"Worker Started ....");
try {
Thread.sleep(20000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(workerId+"Worker finishes.....");
}
}
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class TestExecutor {
public static void main(String[] args) {
ExecutorService executorService=Executors.newCachedThreadPool();
for(int i=0;i<=2;i++){
executorService.submit(new Worker(i));
}
executorService.shutdown();
try {
executorService.awaitTermination(1, TimeUnit.SECONDS);
} catch (InterruptedException e) {
System.out.println("Timeout Happen .....");
}
}
}
This code
try {
executorService.awaitTermination(1, TimeUnit.SECONDS);
} catch (InterruptedException e) {
System.out.println("Timeout Happen .....");
}
doesn't do what you expect it to do.
Throws:
InterruptedException - if interrupted while waiting
from the javadocs. Your code doesn't terminate within the second and the InterruptedException will only be thrown, if the thread was interrupted, while the code is waiting for the executorService to terminate. The correct wait to test whether the executorService actually terminated would be
try {
if(executorService.awaitTermination(1, TimeUnit.SECONDS))
System.out.println("Terminated correctly");
else
System.out.println("Termination failed");
} catch (InterruptedException e) {
e.printStackTrace();
}
And executorService.shutdown() waits for running threads to terminate. So your code will wait the entire 20 seconds, until the submitted runnable terminates and won't accept or start any new Runnables in the meantime. If you want to terminate the Thread in a less gracefull way, you'll have to use executorService.shutdownNow(), which will interrupt running Threads.

Executor service -- not to block main program

I am using ExecutorService and its blocking the main program for some time but I don't want to block the main program.
Here is the code:
public class Test {
public static void main(String[] args) throws InterruptedException, ExecutionException, TimeoutException {
ExecutorService executor = null;
try {
executor = Executors.newFixedThreadPool(1);
System.out.println("Start 1");
Runnable task = new Runnable() {
public void run() {
System.out.println("Start 2");
try {
Thread.sleep(7000);
System.out.println("Start 5");
} catch (Exception e) {
}
}
};
System.out.println("Start 3");
// executor.execute(task);
Future future = executor.submit(task);
Object result = future.get(9, TimeUnit.SECONDS);
System.out.println("Start 4");
} catch (Exception e) {
} finally {
System.out.println("finally");
executor.shutdownNow();
}
}
}
Output:
Start 1
Start 3
Start 2
Start 5
Start 4
finally
Currently it does not print Start 4 until and unless the thread completes the execution. What I am looking for is some mechanism where we can have a timeout and the thread runs in the background and does not block the main thread?
You are using future.get(9, TimeUnit.SECONDS); This will wait for 9 seconds, for the submitted thread to finish.
If you don't need the main program to wait and also don't require anything to be returned by the thread, then use the executor.execute call.
Here is the updated code...
ExecutorService executor = null;
try {
executor = Executors.newFixedThreadPool(1);
System.out.println("Start 1");
Runnable task = new Runnable() {
public void run() {
System.out.println("Start 2");
try {
Thread.sleep(7000);
System.out.println("Start 5");
}
catch (Exception e) {
}
}
};
System.out.println("Start 3");
executor.execute(task);
System.out.println("Start 4");
}
catch (Exception e) {
}
finally {
System.out.println("finally");
executor.shutdown();
}
}
You are not catching timeout exception in current code before printing Start 4 but you are catching Exception after `Start 4' line. So you are not getting desired output in case of timeout.
Change your code
from
Object result = future.get(9, TimeUnit.SECONDS);
to
try {
Object result = future.get(9, TimeUnit.SECONDS);
} catch (CancellationException ce) {
System.out.println("CancellationException ");
} catch (ExecutionException ee) {
System.out.println("ExecutionException ");
} catch (InterruptedException ie) {
System.out.println("InterruptedException ");
Thread.currentThread().interrupt(); // ignore/reset
}
With above code, you always get Start 4 irrespective of time-out of Future task.
Refer to afterExecute method in ThreadPoolExecutor documentation page for more details.
Regarding blocking of main thread, currently you are using blocking get() call on Future. If you don't want to block your main thread, change ExecutorService to ExecutorCompletionService and use new API as per documentation above page.

Producer Consumer in Java using threads never terminates

I have a Producer-Consumer problem to implement in Java, where I want the producer thread to run for a specific amount of time e.g. 1 day, putting objects in a BlockingQueue -specifically tweets, streamed from Twitter Streaming API via Twitter4j- and the consumer thread to consume these objects from the queue and write them to file. I've used the PC logic from Read the 30Million user id's one by one from the big file, where producer is the FileTask and consumer is the CPUTask (check first answer; my approach uses the same iterations/try-catch blocks with it). Of course I adapted the implementations accordingly.
My main function is:
public static void main(String[] args) {
....
final int threadCount = 2;
// BlockingQueue with a capacity of 200
BlockingQueue<Tweet> tweets = new ArrayBlockingQueue<>(200);
// create thread pool with given size
ExecutorService service = Executors.newFixedThreadPool(threadCount);
Future<?> f = service.submit(new GathererTask(tweets));
try {
f.get(1,TimeUnit.MINUTES); // Give specific time to the GathererTask
} catch (InterruptedException | ExecutionException | TimeoutException e) {
f.cancel(true); // Stop the Gatherer
}
try {
service.submit(new FileTask(tweets)).get(); // Wait til FileTask completes
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
service.shutdownNow();
try {
service.awaitTermination(7, TimeUnit.DAYS);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Now, the problem is that, although it does stream the tweets and writes them to file, it never terminates and never gets to the f.cancel(true) part. What should I change for it to work properly? Also, could you explain in your answer what went wrong here with the thread logic, so I learn from my mistake? Thank you in advance.
These are the run() functions of my PC classes:
Producer:
#Override
public void run() {
StatusListener listener = new StatusListener(){
public void onStatus(Status status) {
try {
tweets.put(new Tweet(status.getText(),status.getCreatedAt(),status.getUser().getName(),status.getHashtagEntities()));
} catch (InterruptedException e) {
e.printStackTrace();
Thread.currentTread.interrupt(); // Also tried this command
}
}
public void onException(Exception ex) {
ex.printStackTrace();
}
};
twitterStream.addListener(listener);
... // More Twitter4j commands
}
Consumer:
public void run() {
Tweet tweet;
try(PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("out.csv", true)))) {
while(true) {
try {
// block if the queue is empty
tweet = tweets.take();
writeTweetToFile(tweet,out);
} catch (InterruptedException ex) {
break; // GathererTask has completed
}
}
// poll() returns null if the queue is empty
while((tweet = tweets.poll()) != null) {
writeTweetToFile(tweet,out);
}
} catch (IOException e) {
e.printStackTrace();
}
}
You should check if your Thread classes are handling the InterruptedException, if not, they will wait forever. This might help.

Stop() method in a thread?

In the following example how stop() method is implemented??
What should be done instead of using stop() method?
In my point of view ,When the desired state is suspended, the thread waits using Object.wait. When the thread is resumed, the target thread is notified using Object.notify. but doubtful in case of implentation of stop() in the below example.
Class NewThread implements Runnable {
String name; // name of thread
Thread t;
boolean suspendFlag;
NewThread(String threadname) {
name = threadname;
t = new Thread(this, name);
System.out.println("New thread: " + t);
suspendFlag = false;
t.start(); // Start the thread
}
// This is the entry point for thread.
public void run() {
try {
for(int i = 15; i > 0; i--) {
System.out.println(name + ": " + i);
Thread.sleep(200);
synchronized(this) {
while(suspendFlag) {
wait();
}
}
}
} catch (InterruptedException e) {
System.out.println(name + " interrupted.");
}
System.out.println(name + " exiting.");
}
void mysuspend() {
suspendFlag = true;
}
synchronized void myresume() {
suspendFlag = false;
notify();
}
}
class SuspendResume {
public static void main(String args[]) {
NewThread ob1 = new NewThread("One");
NewThread ob2 = new NewThread("Two");
try {
Thread.sleep(1000);
ob1.mysuspend();
System.out.println("Suspending thread One");
Thread.sleep(1000);
ob1.myresume();
System.out.println("Resuming thread One");
ob2.mysuspend();
System.out.println("Suspending thread Two");
Thread.sleep(1000);
ob2.myresume();
System.out.println("Resuming thread Two");
} catch (InterruptedException e) {
System.out.println("Main thread Interrupted");
}
// wait for threads to finish
try {
System.out.println("Waiting for threads to finish.");
ob1.t.join();
ob2.t.join();
} catch (InterruptedException e) {
System.out.println("Main thread Interrupted");
}
System.out.println("Main thread exiting.");
}
}
The thread automatically stop if it returns the run() function.no need to use the stop() function because stop method is deprecated by java and unsafe to use
Calling stop method will kill the thread on which it is called. A thread must only be killed when there is no use of continuing what a thread is doing. When you will call the stop method, the Thread will stop its execution and will die.
It is preferable to allow thread to complete its run method and kill itslef rather than killing it forcefully.
Calling stop() triggers an exception/error to be thrown in the thread at a random point. If you have access to all the code for the thread it can be used safely, however if this the case, you are far better off supporting interrupts.
Instead of Object.wait/notify, you are likely to be better off using high level concurrency library support i.e. use a Lock which would simplify your code.
For more on stop(); Does Thread.stop() really stop a Thread?
It depends on your threads and what they have to do really.
If they are workers that for example listen to a tcp/ip socket, then you're better off having a volatile boolean inside of the class that says wether or not the loop inside your run() method should continue. Then have your class that extends thread implement a pleaseStop() function which puts the boolean to false, which then causes your run method to finish gracefully (you can even clean up your resources then).
On the other hand, if they are workers that have a finite amount of work to be done, then you should just wait for them to be ready, using the join() functionality.
private void jToggleButton1ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
if (jToggleButton1.isSelected()) {
jToggleButton1.setBackground(Color.green);
jToggleButton1.setText("ON");
//MainClass main = new MainClass();
new Thread(new Runnable() {
#Override
public void run() {
try {
server = new ServerSocket(4400, 500);
do {
socket = server.accept();
ClientHandler cliendHandler = new ClientHandler(socket);
cliendHandler.start();
} while (true);
} catch (IOException ex) {
}
}
}).start();
} else {
try {
server.close();
jToggleButton1.setText("START SERVER");
jToggleButton1.setBackground(Color.red);
} catch (IOException ex) {
Logger.getLogger(Server_Prog.class.getName()).log(Level.SEVERE, null, ex);
}
}
}

Categories