I have a requirement that both Main thread and Executor service should execute in parallel. Main thread should not wait for all threads in executor service to finish. It should continue its execution while executor service is executing its threads.
Example Main Method
public static void main(String[] args) throws InterruptedException, ExecutionException {
String mess = "test completed";
//Start of ExecutorService - ThreadPool of size 500
ExecutorService executorService = Executors.newFixedThreadPool(500);
//Creating 500 tasks to execute
List<AsyncTask> callables = new ArrayList<>();
for(int i=1 ; i<= 500 ; i++){
callables.add(new AsyncTask(i));
}
//Submitting all 500 tasks to execute
List<Future<String>> futures = executorService.invokeAll(callables);
for(Future<String> future : futures){
System.out.println("future.get = " + future.get());
}
executorService.shutdown();
//End of Executor service
//Below code executes only when executor service is finished.
//I want below code to execute in parallel with executor service
//Means It should print this mess before executor service finishes
System.out.println(mess);
}
Callable Task
public class AsyncTask implements Callable<String>{
private int i;
public AsyncTask(int i) {
this.i = i;
}
#Override
public String call() throws Exception {
return "Task " +i;
}
}
OutPut :
future.get = Task 1
future.get = Task 2
future.get = Task 3
future.get = Task 4
.......continues till
future.get = Task 500
test completed
Expected output :
test completed message to be printed during some async tasks are finished or before start of async tasks
Sample output
future.get = Task 1
future.get = Task 2
test completed // Both Main method and Executor service is running in parallel
future.get = Task 3
...........
future.get = Task 500
I have not worked on Threads before, do i miss something ? whole idea of using executor service is to execute some tasks in parallel with main thread right ?
Please suggest me to fix this
ExecutorService.invokeAll will wait until all task was completed, so all code after it would not be executed until ExecutorService.invokeAll was returned. Put the service execution code to another thread will simply solve the problem.
class RunService extends Thread {
RunService () {
}
public void run() {
//Start of ExecutorService - ThreadPool of size 500
ExecutorService executorService = Executors.newFixedThreadPool(500);
//Creating 500 tasks to execute
List<AsyncTask> callables = new ArrayList<>();
for(int i=1 ; i<= 500 ; i++){
callables.add(new AsyncTask(i));
}
//Submitting all 500 tasks to execute
List<Future<String>> futures = executorService.invokeAll(callables);
for(Future<String> future : futures){
System.out.println("future.get = " + future.get());
}
executorService.shutdown();
//End of Executor service
}
}
public static void main(String[] args) throws InterruptedException, ExecutionException {
String mess = "test completed";
RunService rs = new RunService();
rs.Start();
//Below code executes only when executor service is finished.
//I want below code to execute in parallel with executor service
//Means It should print this mess before executor service finishes
System.out.println(mess);
}
Related
A thread is executing task to print numbers from 0 to n, and sleeps for 4000 ms after every print statement. Somewhere in the middle thread gets interrupted. Now when the same thread starts its execution, where will it start from , will it start printing the numbers from 0 to n again, or it will print numbers from where it got interrupted.
In both cases what are the reasons and how it is being handled?
public class Main {
public static void main(String[] args) throws InterruptedException {
SleepTest sleepTest = new SleepTest();
Thread thread = new Thread(sleepTest);
thread.start();
thread.interrupt();
}
}
public class SleepTest implements Runnable{
static int sleep = 10;
public void run(){
for (int i =0; i<10; i++){
System.out.println(i);
try {
Thread.currentThread().interrupt();
Thread.sleep(4000);
} catch (InterruptedException exception) {
exception.printStackTrace();
}
System.out.println(Thread.interrupted());
}
}
Calling a interrupt() on a thread object can only suggest thread to stop. It is not guarantee that the thread will stop.
It completely depends on the implementation of run() method of thread.
In your case in run() you are catching the InterruptedException and you are printing the exception trace but not stopping the thread. Thats why thread will never stop on InterruptedException and continue the execution.
It may look like thread is getting stopped(by seeing exception trace) when see the output on console.
Refer interrupt interrupted isinterrupted in Java
All Thread.currentThread().interrupt() does is update the value of field interrupted to true.
Let's see the program's flow and how the interrupted field is assigned values:
public class Main {
public static void main(String[] args) throws InterruptedException {
SleepTest sleepTest = new SleepTest();
Thread thread = new Thread(sleepTest, "Sub Thread"); // Give a name to this thread
thread.start(); // main thread spawns the "Sub Thread". Value of "interrupted" - false
thread.interrupt(); // called by main thread. Value of "interrupted" - true
}
}
public class SleepTest implements Runnable{
static int sleep = 10;
public void run(){
System.out.println(Thread.currentThread().getName()+" "+Thread.interrupted()); // prints "Sub Thread true"
for (int i =0; i<10; i++){
System.out.println(i);
try {
Thread.currentThread().interrupt(); // no matter what value is for interrupted, it is assigned the value "true"
Thread.sleep(4000); // Can't call sleep with a "true" interrupted status. Exception is thrown. Note that, when the exception is thrown, the value of interrupted is "reset", i.e., set to false
} catch (InterruptedException exception) {
exception.printStackTrace(); // whatever
}
System.out.println(Thread.interrupted()); // returns the value of interrupted and resets it to false
}
}
To answer
where will it start from , will it start printing the numbers from 0
to n again, or it will print numbers from where it got interrupted.
Calling interrupt will not cause make it start over because all it is doing at this call is set value interrupted to false (and not modifying anything else).
When I run this code, stage shows after task finishing. Why does it happend?
How to make a stage appear before a task?
private List<SensorEntity> detectSensors() throws URISyntaxException {
Task<List<SensorEntity>> task = new TryDetectTask(sensorForDiscover, wifiController);
ProgressIndicator indicator = new ProgressIndicator();
indicator.setProgress(ProgressIndicator.INDETERMINATE_PROGRESS);
indicator.progressProperty().bind(task.progressProperty());
Stage stage = new Stage();
stage.setHeight(100);
stage.setWidth(200);
stage.initModality(WINDOW_MODAL);
stage.setScene(new Scene(indicator));
stage.show();
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<List<SensorEntity>> futureTask = executor.submit(task, null);
try {
return futureTask.get(30, SECONDS);
}
catch (InterruptedException | ExecutionException | TimeoutException e) {
log.error(e);
e.printStackTrace();
}
executor.shutdown();
return null;
}
Same result for pane.getScene().setRoot(), alert.show(), Platform.runLater and other, but showAndWait() works fine.
futureTask.get(30, SECONDS) blocks until the result is available or until the 30 seconds have passed. Since you're doing this on the JavaFX application thread any updates to the GUI are blocked during this time.
showAndWait "works" since this call ensures the GUI still updates, but this method only returns when the stage is closed which means you simply freeze the GUI later.
You'd be better off passing a Consumer<List<SensorEntity>> to the method that executes the code using the task result.
private void detectSensors(Consumer<List<SensorEntity>> consumer) throws URISyntaxException {
final boolean[] boolRef = new boolean[1];
Task<List<SensorEntity>> task = new TryDetectTask(sensorForDiscover, wifiController);
task.setOnSucceeded(evt -> {
if (!boolRef[0]) {
boolRef[0] = true;
// submit result unless timeout happened
consumer.accept(task.getValue());
}
});
ProgressIndicator indicator = new ProgressIndicator();
indicator.setProgress(ProgressIndicator.INDETERMINATE_PROGRESS);
indicator.progressProperty().bind(task.progressProperty());
Stage stage = new Stage();
stage.setHeight(100);
stage.setWidth(200);
stage.initModality(WINDOW_MODAL);
stage.setScene(new Scene(indicator));
stage.show();
// a thread does not need to be shut down
Thread thread = new Thread(task);
thread.setDaemon(true);
PauseTransition pause = new PauseTransition(Duration.seconds(30));
pause.setOnFinished(evt -> {
if (!boolRef[0]) {
boolRef[0] = true;
// submit null unless task has finished successfully
consumer.accept(null);
}
});
thread.start();
pause.play();
}
I was trying below code.
public class IteratorFailFastTest {
private List<Integer> list = new ArrayList<>();
public IteratorFailFastTest() {
for (int i = 0; i < 10; i++) {
list.add(i);
}
}
public void runUpdateThread() {
Thread thread2 = new Thread(new Runnable() {
public void run() {
for (int i = 10; i < 20; i++) {
list.add(i);
}
}
});
thread2.start();
}
public void runIteratorThread() {
Thread thread1 = new Thread(new Runnable() {
public void run() {
ListIterator<Integer> iterator = list.listIterator();
while (iterator.hasNext()) {
Integer number = iterator.next();
System.out.println(number);
}
}
});
thread1.start();
}
public static void main(String[] args) {
// TODO Auto-generated method stub
IteratorFailFastTest tester = new IteratorFailFastTest();
tester.runIteratorThread();
tester.runUpdateThread();
}
}
It is throwing ConcurrentModificationException sometimes and at times running successfully.
What I don't understand is, since there are 2 different methods each containing one thread. They will execute one by one. When one thread finishes modifying the list, Thread 2 will start iterating.
I also referred to this link(Why no ConcurrentModificationException when one thread iterating (using Iterator) and other thread modifying same copy of non-thread-safe ArrayList), but it is different scenario.
So, Why is it throwing this exception? Is it because of threads?
Can somebody explain?
You are starting two threads and then doing no further synchronization.
Sometimes, both threads will be running at the same time, and you will get the CME. Other times, the first thread will finish before the second thread actually starts executing. In that scenario won't get a CME.
The reason you get the variation could well be down to things like load on your system. Or it could simply be down to the fact that the thread scheduler is non-deterministic.
Your threads actually do a tiny amount of work, compared to the overheads of creating / starting a thread. So it is not surprising that one of them can return from its run() method very quickly.
I have below code, the doTransaction method is getting invoked after 20 seconds, could any one tell me why its taking that long to invoke doTransaction method.
Its not happening always its happening very rarely. Any help on this is appreciated.
Thanks,
ExecutorService service = Executors.newSingleThreadExecutor();
TransactionTask task = new TransactionTask(object);
Future<Result> future = service.submit(task);
Result r = future.get(20000, TimeUnit.MILLISECONDS);
class TransactionTask implements Callable<Result> {
private Request req = null;
public TransactionTask(Request trx){
this.req = trx;
}
#Override
public Result call() throws Exception {
Result o = doTransaction(req);
return o;
}
}
The above behavior could be explained if you submit multiple tasks.
The ExecutorService you created is single threaded, so it could only execute only one task concurrently. Other tasks if submitted will be in queue and will start executing if the former task is terminated/completed
It executes only after 20 seconds because in future.get(20000, TimeUnit.MILLISECONDS); you cancel the already running task. Could you check that you are not getting CancellationException.
Edit:
Since you are using Tomcat which is concurrent in execution, I would suggest, you use multithread instead of single thread if not necessary:- Executors.newFixedThreadPool(N); for having N tasks executing concurrently and increase the timout
I have a class ThreadClass which looks as follows:
public class ThreadClass extends Thread{
String msg;
public void run()
{
for(int i=0;i<=5;i++)
{
System.out.println("Run method: "+msg);
}
}
ThreadClass(String mg)
{
msg=mg;
}
}
public class MainThreadClass {
public static void main(String[] args) {
ThreadClass dt1=new ThreadClass("Thread 1");
ThreadClass dt2=new ThreadClass("Thread 2");
dt1.start();
dt2.start();
System.out.println("Finished");
}
}
the output I am getting is:
Run method: Thread 1
Finished
Run method: Thread 1
Run method: Thread 2
Run method: Thread 2
Run method: Thread 2
Run method: Thread 2
Run method: Thread 2
Run method: Thread 2
Run method: Thread 1
Run method: Thread 1
Run method: Thread 1
Run method: Thread 1
The output I would like to achieve would be:
Run method: Thread 1
Run method: Thread 1
Run method: Thread 2
Run method: Thread 2
Run method: Thread 2
Run method: Thread 2
Run method: Thread 2
Run method: Thread 2
Run method: Thread 1
Run method: Thread 1
Run method: Thread 1
Run method: Thread 1
Finished
so the string finished is printed out when these two threads terminate. How to do it?
Wait for each thread to exit using join():
public class MainThreadClass {
public static void main(String[] args) {
ThreadClass dt1=new ThreadClass("Thread 1");
ThreadClass dt2=new ThreadClass("Thread 2");
dt1.start();
dt2.start();
dt1.join();
dt2.join();
System.out.println("Finished");
}
}
[Sorry about the lousy formatting, for some reason I can't get this looking any nicer. IE issue maybe?]
You need to determine when a thread was finished:
// Create and start a thread
Thread thread = new MyThread();
thread.start();
// Check if the thread has finished in a non-blocking way
if (thread.isAlive()) {
// Thread has not finished
} else {
// Finished
}
// Wait for the thread to finish but don't wait longer than a
// specified time
long delayMillis = 5000; // 5 seconds
try {
thread.join(delayMillis);
if (thread.isAlive()) {
// Timeout occurred; thread has not finished
} else {
// Finished
}
} catch (InterruptedException e) {
// Thread was interrupted
}
// Wait indefinitely for the thread to finish
try {
thread.join();
// Finished
} catch (InterruptedException e) {
// Thread was interrupted
}
Or use an ExecutorService. Here is a excerpt from a class I have that does similar to yours.
ExecutorService l_service = Executors.newFixedThreadPool(l_number_threads);
List<Future<T>> l_results = null;
try {
l_results = l_service.invokeAll(a_tasks);
} catch (InterruptedException ex) {
throw ex;
}
l_service.shutdownNow();