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();
}
}
I need to implement a scheduled executor service which runs a thread in an interval every x seconds.
The thread execution should be interrupted in case it took more than y seconds.
I have tried to implement the solution using the ScheduledExecutorService that has a configurable parameter for the interval but does not have one for the timeout.
I have a few ideas in mind and I would like to hear your suggestion for implementations/ techniques.
Does this help?Task begins every 10 seconds,and it takes 5 seconds to be done,you will get a InterruptedException when timedout(3 seconds).
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class Worker implements Runnable {
ListeningExecutorService listeningExecutorService;
ScheduledExecutorService scheduledExecutorService;
Runnable task;
public Worker(ListeningExecutorService listeningExecutorService, ScheduledExecutorService scheduledExecutorService, Runnable task) {
this.listeningExecutorService = listeningExecutorService;
this.scheduledExecutorService = scheduledExecutorService;
this.task = task;
}
#Override
public void run() {
ListenableFuture future = listeningExecutorService.submit(task);
Futures.withTimeout(future, 3, TimeUnit.SECONDS, scheduledExecutorService);
}
public static void main(String[] args) {
ListeningExecutorService listeningExecutorService = MoreExecutors
.listeningDecorator(Executors.newCachedThreadPool());
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(5);
Worker worker = new Worker(listeningExecutorService, scheduledExecutorService, new Runnable() {
#Override
public void run() {
System.out.println("Now begin: " + new Date());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Now end: " + new Date());
}
});
scheduledExecutorService.scheduleAtFixedRate(worker, 0, 10, TimeUnit.SECONDS);
}
}
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.
Below code :
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;
public class ThreadTest {
private static int counter = 0;
private static ExecutorService executorService = Executors.newCachedThreadPool();
private static List<Integer> intValues = new ArrayList<Integer>();
public static void main(String args[]){
for(int counter = 0; counter < 10; ++counter){
intValues.add(testCallback());
}
for(int i : intValues){
System.out.println(i);
}
System.exit(0);
}
public static Integer testCallback() {
Future<Integer> result = executorService.submit(new Callable<Integer>() {
public Integer call() throws Exception {
counter += 1;
Thread.sleep(500);
return counter;
}
});
try {
return result.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
return null;
}
}
Outputs :
1
2
3
4
5
6
7
8
9
10
This program takes approx 5 seconds to run. I am trying to execute multiple invocations of testCallback method in a seperate thread so I would expect this method to run in 10 threads concurrently where each thread uses approx 500 miliseconds of time. So over all I expet the program to run in < 1 second.
Why is counter not being invoked in seperate threads concurrently ?
result.get();
This is a blocking call that waits for the task to complete.
Therefore, you're waiting for each task to finish before starting the next one.