I have written a small program to check behavior of Completable Future. I have not overridden the common pool.
I did not found any shut down method and when i print active number of thread at the end, i found my thread active.
My question is when they will end, if i am using it in life application?
And do they create to many thread if i use it in public Api, who have much traffic?
My samlple code
`
package rar;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
public class Rar {
public static void main(String[] args) {
Rar r = new Rar();
Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
System.out.println(threadSet); r.dfo(); threadSet =
Thread.getAllStackTraces().keySet(); System.out.println("uyuuuu"+threadSet);
}
private static void doTask3() {
for(int i=0; i<5;i++) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.print(3);
}
}
public void dfo() {
System.out.println("In main");
ExecutorService executor = Executors.newFixedThreadPool(3);
CompletableFuture<Void> thenCompose =CompletableFuture.allOf(
CompletableFuture.runAsync(() -> doTask1()),
CompletableFuture.runAsync(() -> doTask2(2)),
CompletableFuture.runAsync(() -> doTask3()));
//executor.shutdown();
try {
Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
System.out.println(threadSet);
thenCompose.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
System.out.println("Exiting main");
Set<Thread> threadSeWt = Thread.getAllStackTraces().keySet();
System.out.println(threadSeWt);
}
private void doTask2(int num) {
for(int i=0; i<5;i++) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.print("4");
}
}
private int doTask1() {
for(int i=0; i<5;i++) {
try {
Thread.sleep(5001);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.print(1);
}
return 5;
}
}
`
Sample Output:
[Thread[Finalizer,8,system], Thread[Attach Listener,5,system], Thread[Signal Dispatcher,9,system], Thread[Reference Handler,10,system], Thread[main,5,main]]
In main
[Thread[Finalizer,8,system], Thread[ForkJoinPool.commonPool-worker-1,5,main], Thread[main,5,main], Thread[ForkJoinPool.commonPool-worker-2,5,main], Thread[Attach Listener,5,system], Thread[ForkJoinPool.commonPool-worker-3,5,main], Thread[Signal Dispatcher,9,system], Thread[Reference Handler,10,system]]
431413431431431Exiting main
[Thread[Finalizer,8,system], Thread[ForkJoinPool.commonPool-worker-1,5,main], Thread[main,5,main], Thread[ForkJoinPool.commonPool-worker-2,5,main], Thread[Attach Listener,5,system], Thread[ForkJoinPool.commonPool-worker-3,5,main], Thread[Signal Dispatcher,9,system], Thread[Reference Handler,10,system]]
uyuuuu[Thread[Finalizer,8,system], Thread[ForkJoinPool.commonPool-worker-1,5,main], Thread[main,5,main], Thread[ForkJoinPool.commonPool-worker-2,5,main], Thread[Attach Listener,5,system], Thread[ForkJoinPool.commonPool-worker-3,5,main], Thread[Signal Dispatcher,9,system], Thread[Reference Handler,10,system]]
The executor in your dfo() method is not used.
When you use runAsync() method, it runs on the common pool. That's why you see ForkJoinPool in your debug messages.
The size of that pool is limited by default by "number of your CPU cores - 1".
Try running 20 tasks, and you'll see that your thread count stops growing, once it reaches the maximum.
You don't need to stop the threads of the ForkJoinPool. From the documentation:
its threads are slowly reclaimed during periods of non-use
I can't execute Runnables(delayed tasks in a queue), that have been returned in an list of Runnables after invoking of shutdownNow() on ScheduledThreadPoolExecutor object.
I've tried some ways to do it: you can get list size, one of the Runnable objects itself, invoke isDone() query, but I haven't coped to run them.
CAN they be executed and HOW if possible?
See please code below. Thank you.
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor;
public class ExecuteExisitingDelayedTasksAfterShutdownPolicy1 {
private static int count = 0;
private static class Task implements Runnable {
private String name;
public Task(String name) {
this.name = name;
count++;
}
#Override
public void run() {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
return;
}
System.out.printf("\n%s: " + getName(), Thread.currentThread().getName());
}
public String getName() {
return name;
}
}
public static void main(String[] args) throws InterruptedException, ExecutionException {
ScheduledThreadPoolExecutor stpe = new ScheduledThreadPoolExecutor(10, new ThreadPoolExecutor.DiscardPolicy());
stpe.setExecuteExistingDelayedTasksAfterShutdownPolicy(true);
List<Runnable> queue = null;
for (int i = 0; i < 100; i++) {
stpe.execute(new Task("Task " + count));
if (i == 50) {
Thread.sleep(1000);
queue = stpe.shutdownNow();
System.out.print("\nQueue SIZE: " + queue.size());
}
}
Thread.sleep(3000);
System.out.print("\n" + queue.get(0));
#SuppressWarnings("unchecked")
FutureTask<Task> ftask = (FutureTask<Task>) queue.get(0);
ExecutorService ses = Executors.newSingleThreadExecutor();
/**
* all of the next.. doesn't work: tasks returned in a queue are likely
to be
* unrunnable
*/
ftask.get().run();
System.out.println(ftask.get().name);
ses.execute(ftask);
queue.get(0).run();
}
}
This question already has answers here:
How do you kill a Thread in Java?
(17 answers)
How can I pass a parameter to a Java Thread?
(19 answers)
Returning value from Thread
(9 answers)
Closed 4 years ago.
How can I kill a thread if the time for him over or it return me the data?
how I start it
I need to pass a arg for him
You can use Future.get with a timeout.
If the timeout is exceeded, you'll get a TimeoutException, which you can handle any way you like.
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class Main
{
private static int foo(final int arg)
{
/* Uncomment to see future get interrupted
try
{
Thread.sleep(2000);
}
catch (InterruptedException e) { } */
return 1000 + arg;
}
public static void main(String[] args)
throws ExecutionException, InterruptedException
{
final ExecutorService executor = Executors.newSingleThreadExecutor();
final Future<Integer> future = executor.submit(() -> Main.foo(3));
try
{
int result = future.get(1, TimeUnit.SECONDS);
System.out.println(result);
}
catch (TimeoutException e)
{
future.cancel(true);
}
executor.shutdown();
}
}
Hi I am trying to run below code, and after executor is terminated I am expecting the count of remaining task to be 0, but for some reason it's more then 100 when it satisfy below condition.
while(executor.isTerminated()) {
System.out.println("Total Task Remaining : " + ExecutorServiceExample.task.size());
System.out.println("*** Executor Terminated ***");
break;
}
Code Snippet.
package test;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class ExecutorServiceExample {
public static volatile Set<String> task = new HashSet<String>();
public static void main(String args[]) {
ExecutorService executor = Executors.newFixedThreadPool(2000);
for (int i = 0; i < 10000; i++) {
String name = "task#" + i;
task.add(name);
Runnable runner = new TaskPrint(name);
executor.execute(runner);
}
try {
executor.shutdown();
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
if (executor.isTerminated()) {
System.out.println("Total Task Remaining : " + ExecutorServiceExample.task.size());
System.out.println("*** Executor Terminated ***");
}
} catch (InterruptedException ignored) {
}
}
}
class TaskPrint implements Runnable {
private final String name;
public TaskPrint(String name) {
this.name = name;
}
public void run() {
ExecutorServiceExample.task.remove(name);
}
}
Something strange with the result based on the number of tasks.
Output for 100 tasks.
Total Task Remaining : 0
*** Executor Terminated ***
Output for 1000 tasks.
Total Task Remaining : 0
*** Executor Terminated ***
Output for 10000 tasks.
Total Task Remaining : -27
*** Executor Terminated ***
Output for 100000 tasks.
Total Task Remaining : 1205
*** Executor Terminated ***
HashSet is not thread safe. You can create a synchronizedSet with
public static volatile Set<String> task = Collections.synchronizedSet(new HashSet<String>());
below is my code. I am populating a list with size 3500000 by thread. first i populated the list by one thread. And This thread will return a list of string that contains 3500000 items.
This Process Takes 5 seconds to execute.
Then, I created another Thread and divided the entire task by two and distributed them to the threads.
First thread will populate the list of string of 1900000 items, second thread will return (3500000-1900000=1600000) items. The two process are running in parallel. So, the should take less time.
But, for this case, the total computing time is also 5 seconds.
Please anybody help me out to find out where I am doing wrong?
I badly need to minimize the execution time. How I can minimize the time?
package callablefutures;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.Calendar;
import java.util.concurrent.TimeUnit;
import java.util.Date;
public class CallableFutures {
private static final int NTHREDS = 10;
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(NTHREDS);
List<Future<List<String>>> list = new ArrayList<Future<List<String>>>();
List<List<String>> lst=new ArrayList();
List<String> list1=new ArrayList();
List<String> list2=new ArrayList();
Runtime rt = Runtime.getRuntime();
long prevFree = rt.freeMemory();
long startTime=System.currentTimeMillis();
Callable<List<String>> worker = new MyCallable(list1,0,1900000);
Future<List<String>> submit = executor.submit(worker);
list.add(submit);
Callable<List<String>> worker1 = new MyCallable(list2,1900000,3500000);
Future<List<String>> submit1 = executor.submit(worker1);
list.add(submit1);
long sum = 0;
System.out.println(list.size());
for (Future<List<String>> future : list) {
try {
lst.add(future.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
executor.shutdown();
long endTime=System.currentTimeMillis();
System.out.println("Total Time Taken: " + (endTime-startTime)/1000%60 +" Seconds");
System.out.println("Total Memory Taken (MB): " + ((prevFree-rt.freeMemory())/1024)/1024);
}
}
package callablefutures;
import java.util.concurrent.Callable;
import java.util.List;
import java.util.ArrayList;
public class MyCallable implements Callable<List<String>>{
public List<String> StrList=new ArrayList();
public int sIndex,eIndex;
public MyCallable(List<String> oList,int si,int ei)
{
this.StrList=oList;
this.sIndex=si;
this.eIndex=ei;
}
#Override
public List<String> call() throws Exception {
for (int i = this.sIndex; i < this.eIndex; i++) {
this.StrList.add("ID "+i);
}
return this.StrList;
//return this.StrList;
}
}
You are creating about 128 MB of data, which will be larger than your L3 cache so you will be pushing data out to main memory and this is typically easy to saturate with one thread. If you want threads to run concurrently you want them to be limited to 256 KB each (as they each have their own L2 cache assuming they run on different cores) or 128 KB each if on the same core.