I am trying execute a runnable a few times, and if it doesn't finished within x seconds 3 times, I will cancel it.
The code I'm using to simulate the situation where the task needs to be cancelled is as follows. From the output I can see that an InterruptedException was thrown and caught accordingly, but the task keeps running.
It seems that the first two times the task was run before the TimeoutException was thrown 3 times, those two runs kept on running until they are finished. I'm wondering if there is a way to stop those two runs from completing ?
public class SomeClass {
private static int c =0;
public static void main(String[] args){
Runnable dummyRunnable = new Runnable() {
#Override
public void run() {
System.out.println("Hello from dummyRunnable!");
for (int i =0; i< 10; i++){
try {
//simulate work here
if (!Thread.currentThread().isInterrupted()) Thread.sleep(5000);
System.out.println("thread sleeps for the " + i + " time!");
} catch (InterruptedException ie){
System.out.println("InterruptedException catched in dummyRunnable!");
//Thread.currentThread().interrupt(); //this has no effects
break;
}
}
}
};
BlockingQueue<Runnable> blockingQueue = new ArrayBlockingQueue<Runnable>(10 * 3, true);
ThreadPoolExecutor executor = new ThreadPoolExecutor(3, 3, Long.MAX_VALUE, TimeUnit.MILLISECONDS, blockingQueue);
for (int i =0; i< 5; i++){
Future<?> task = executor.submit(dummyRunnable);
try{
Thread.sleep(1000);
task.get(2000, TimeUnit.MILLISECONDS);
} catch (TimeoutException te){
c++;
System.out.println("TimeoutException from a task!");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (c==3){
System.out.println("cancelling task...");
task.cancel(true);
break;
}
}
}
}
}
I don't get it what you are actually trying to simulate. I would expect a simulation like paying with card (60 secs time-out to finish a task) or perhaps a secretary in a doctor-patient situation.
The way it stand now you are creating the 5 objects in the Future.
If you want more control off your threads, you should think about using synchronized methods and a monitor that handles the threads for you.
Usually when starting a thread you should go with
new Thread(new Task(object or generics)).start();
Thread.sleep(2000); // calls this thread to wait 2 secs before doing other task(s)
Before doing some hardcore concurrency(multithreading), you should read some java tutorial to get some inspiration...
http://docs.oracle.com/javase/tutorial/essential/concurrency/index.html
Related
So I have a function which looks like this
ExecutorService executorService = Executors.newFixedThreadPool(2000);
Boolean getMore = true;
try{
While (getMore) {
JSONObject response = getPaginatedResponse();
int[] ar = response.get("something");
if (ar.length > 0) {
// loop through the array and invoke executorService.submit() for each
}
else { getMore = false; }
}
executorService.shutdown();
try {
System.out.println("waiting for tasks to complete, termination starting at : "+java.time.LocalDateTime.now());
executorService.awaitTermination(15, TimeUnit.MINUTES);
} catch (InterruptedException e) {
throw new Exception("loading was interrupted... thread pool timed out!");
}
} catch (Exception) {
System.out.println("Fatal error");
}
My issue is that the each of these threads invoke x number of threads, which in turn each call an API and processes its response, the implementation stops execution after all the "First-level" threads gets fired, but not necessarily all the second level ones, which is crucial for my program, how or where can I invoke the executerService.shutdown() to make sure that all the threads were called.
you can put executorService.shutdown(); inside finally block of exception
I need to execute two tasks in parallel and wait for them to complete. Also I need the result from the second task, for that I am using Future.
My question is that DO I need executor.awaitTermination to join the tasks or Future.get() will take care of it. Also is there a better way to achieve this with Java 8?
public class Test {
public static void main(String[] args) {
test();
System.out.println("Exiting Main");
}
public static void test() {
System.out.println("In Test");
ExecutorService executor = Executors.newFixedThreadPool(2);
executor.submit(() -> {
for(int i = 0 ; i< 5 ; i++) {
System.out.print("["+i+"]");
try {
Thread.sleep(1000);
} catch (Exception e) {e.printStackTrace();}
}
});
Future<String> result = executor.submit(() -> {
StringBuilder builder = new StringBuilder();
for(int i = 0 ; i< 10 ; i++) {
System.out.print("("+i+")");
try {
Thread.sleep(1000);
} catch (Exception e) {e.printStackTrace();}
builder.append(i);
}
return builder.toString();
});
System.out.println("shutdown");
executor.shutdown();
// DO I need this code : START
System.out.println("awaitTermination");
try {
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
} catch (InterruptedException e) {
System.out.println("Error");
}
// DO I need this code : END
System.out.println("Getting result");
try {
System.out.println(result.get());
}
catch (InterruptedException e) {e.printStackTrace();}
catch (ExecutionException e) {e.printStackTrace();}
System.out.println("Exiting Test");
}
}
OUTPUT with awaitTermination:
In Test
[0]shutdown
(0)awaitTermination
[1](1)[2](2)[3](3)[4](4)(5)(6)(7)(8)(9)Getting result
0123456789
Exiting Test
Exiting Main
OUTPUT without awaitTermination:
In Test
[0]shutdown
Getting result
(0)[1](1)[2](2)[3](3)[4](4)(5)(6)(7)(8)(9)0123456789
Exiting Test
Exiting Main
From the get javadoc:
Waits if necessary for the computation to complete, and then retrieves its result.
get will wait for the second task only.
From the awaitTermination javadoc:
Blocks until all tasks have completed execution after a shutdown request, or the timeout occurs, or the current thread is interrupted, whichever happens first.
awaitTermination will wait for all tasks.
You should use CompletableFuture API
You can run a process async like follow:
CompletableFuture.supplyAsync( () -> { ... } );
It returns a future, and you can add a callback which will be called when process is finished and result is available.
For example:
CompletableFuture.runAsync( () -> {
// Here compute your string
return "something";
} ).thenAccept( result -> {
// Here do something with result (ie the computed string)
} );
Note that this statement uses internally the ForkJoinPool#commonPool() to execute the process async, but you can also call this statement with your own ExecutorService if you want. In both case, in order to be sure not exiting before tasks are completed, you need to call either get() (which is blocking) on each future of submitted tasks, or wait for the executor to shutdown.
I have used two different approach to measure time of threads but result are not matching
**Public void Main()**
{
Timer timer = new Timer();
int timetotal;
timer.start();
int numberOfThreads=5;
ExecutorService pool= Executors.newFixedThreadPool(numberOfThreads);
List<Future<Boolean>> futureList = new ArrayList<Future<Boolean>>();
Set<ReadProcess_MongoDB> callList = new HashSet<ReadProcess_MongoDB>();
CompletionService<ReadProcess_MongoDB> taskCompletionService;
taskCompletionService = new ExecutorCompletionService<ReadProcess_MongoDB>(pool);
Collection<Callable<ReadProcess_MongoDB>> list;
list = new LinkedList<Callable<ReadProcess_MongoDB>>();
for(int i=0;i<numberOfThreads;i++)
list.add((Callable<ReadProcess_MongoDB>) new ReadProcess_MongoDB(i));
try {
for (Callable<ReadProcess_MongoDB> callable : list) {
taskCompletionService.submit(callable);
}
for (int i = 0; i < list.size(); i++) {
Future<ReadProcess_MongoDB> result = taskCompletionService.take();
}
} catch (InterruptedException e) {
// no real error handling. Don't do this in production!
e.printStackTrace();
} catch (ExecutionException e) {
// no real error handling. Don't do this in production!
e.printStackTrace();
}
finally {
pool.shutdown();
System.out.println("Done :)");
timer.stop();
System.out.println("Total consumed Time"+ timer.elapsed());
}
Other time I put in Call method()
**public String call()**
{
Timer timer = new Timer();
int timetotal;
timer.start();
DBCursor cursor = coll.find(whereQuery);
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
Logger.getLogger(ReadProcess_MongoDB.class.getName()).log(Level.SEVERE, null, ex);
}
timer.stop();
usedTimeForQueryProcess = timer.elapsed();
System.out.println("Thread Number="+this.threadNumber+ " MongoDB_readQuery used time "+usedTimeForQueryProcess);
System.out.println("runing.....");
return Objects.toString(usedTimeForQueryProcess);
}
In call Function, system print time of every thread and in Main function only display totaltime.Here I try check manually ,but both time are not matching .But bigger problem is Main function show less time than total time of all threads(Call function).
I have also tried to return used time from Call function But it is also create problem convert to long (especially runtime problem ).
Time of Both function
Main function time =289
Call function time=510(5 thread).
Would please somebody expain why this happening and how i can make right measurement ?
The Main time is lower than the total of each of your jobs because they are running in parallel. If you reduce your thread pool size down to 1 then you will the numbers be more like what you expect.
This is one of the benefits of doing multithreaded programming, getting more work done in less time than if it were done sequentially.
This question already has answers here:
Parallel Computing In Java [closed]
(3 answers)
Closed 8 years ago.
I'm making a twitter analysis software with java and I want to create two threads that run in parallel: One is to stream the tweets using twitter streaming API and one is to analyze. I'm not sure of how to start .
Taken right from a java tutorial. Let me know if you have specific quesitons:
public class SimpleThreads {
// Display a message, preceded by
// the name of the current thread
static void threadMessage(String message) {
String threadName =
Thread.currentThread().getName();
System.out.format("%s: %s%n",
threadName,
message);
}
private static class MessageLoop
implements Runnable {
public void run() {
String importantInfo[] = {
"Mares eat oats",
"Does eat oats",
"Little lambs eat ivy",
"A kid will eat ivy too"
};
try {
for (int i = 0;
i < importantInfo.length;
i++) {
// Pause for 4 seconds
Thread.sleep(4000);
// Print a message
threadMessage(importantInfo[i]);
}
} catch (InterruptedException e) {
threadMessage("I wasn't done!");
}
}
}
public static void main(String args[])
throws InterruptedException {
// Delay, in milliseconds before
// we interrupt MessageLoop
// thread (default one hour).
long patience = 1000 * 60 * 60;
// If command line argument
// present, gives patience
// in seconds.
if (args.length > 0) {
try {
patience = Long.parseLong(args[0]) * 1000;
} catch (NumberFormatException e) {
System.err.println("Argument must be an integer.");
System.exit(1);
}
}
threadMessage("Starting MessageLoop thread");
long startTime = System.currentTimeMillis();
Thread t = new Thread(new MessageLoop());
t.start();
threadMessage("Waiting for MessageLoop thread to finish");
// loop until MessageLoop
// thread exits
while (t.isAlive()) {
threadMessage("Still waiting...");
// Wait maximum of 1 second
// for MessageLoop thread
// to finish.
t.join(1000);
if (((System.currentTimeMillis() - startTime) > patience)
&& t.isAlive()) {
threadMessage("Tired of waiting!");
t.interrupt();
// Shouldn't be long now
// -- wait indefinitely
t.join();
}
}
threadMessage("Finally!");
}
}
You can start by looking at java.lang.Thread and java.lang.Runnable.
The most basic way to create a thread is to extend Thread or override Runnable.
Simple, a thread is already a seperate process. So two threads are two seperate processes.
ie.
Thread streamThread = new Thread(new Runnable()); // You have to implement the run() method
streamThread.start();
Thread analyzeThread = new Thread(new Runnable()); // You have to implement the run() method
analyzeThread.start();
That's all there is to it.
I m having a server code to process an image.
Now there are n number of requests which tries to execute the code which results in OutOfMemory error or the server to hang and the server goes to not responding state.
To stop the code from executing at once all the requests I m limiting to execute the code one at a time using the below method where i have a variable
if the variable is 10 then wait for the variable to come at 0
if at 0 then set it to 10 then execute the code
run the code and finally set i to 0
The code here -
static newa.Counter cn;
public int getCounta() {
return cn.getCount();
}
public void setCounta(int i) {
cn = new newa.Counter();
cn.setCount(i);
}
at the function i m doing this -
public BufferedImage getScaledImage(byte[] imageBytes)
{
int i=0;
Boolean b = false;
BufferedImage scaledImage = null;
newa.NewClass1 sc = new newa.NewClass1();
try {
sc.getCounta();
} catch (NullPointerException ne) {
sc.setCounta(0);
}
i = sc.getCounta();
if(i==0)
{
sc.setCounta(10);
b = true;
}
else
{
while( b == false)
{
try
{
Thread.sleep(2000);
i = sc.getCounta();
if( i==0)
{
sc.setCounta(10);
b = true;
System.out.println("Out of Loop");
}
} catch (InterruptedException ex) {
System.out.println("getScaledImage Thread exception: " + ex);
}
}
}
..... execute further code
try { } catch { } finally { sc.setCounta(0); }
}
Is there any way I can have this simplified using the Runnable interface or something as I don't know how to do multi-threading.
Forget about the counter and use a synchronized method. Changed your method head to this:
public synchronized BufferedImage getScaledImage(byte[] imageBytes)
This lets all the threads entering the method wait until no other thread is executing the method.
If you want only a small number of threads doing the processing you can use Executor framework to have a thread pool of 10 threads. This will ensure that at one time maximum of 10 threads will be processing the requests.