ExecutorService Java thread limit - java

I am using ExecutorService for creating Thread. In the run method, its processing a time consuming operations. It takes nearly upto 10 seconds to complete it. For testing, here I am using Thread.sleep(10000);
My question is, If I use newFixedThreadPool as 2000, will it really execute 2000 threads at a time?
public class ThreadPoolTest {
public static void main(String[] args) {
System.out.println(new Date());
ExecutorService executor = Executors.newFixedThreadPool(2000);
IntStream.range(0, 2000).forEach(
i -> {
Runnable worker = new WorkerThread("WorkerThread-" + i);
executor.submit(worker);//calling execute method of ExecutorService
}
);
executor.shutdown();
while (!executor.isTerminated()) { }
System.out.println("Finished all threads");
System.out.println("Main thread finished");
System.out.println(new Date());
}
}
public class WorkerThread implements Runnable{
private String name;
public WorkerThread(String s){
this.name=s;
}
public void run() {
System.out.println(Thread.currentThread().getName()+" (Start) message = "+name);
processData();
}
private void processData(){
try { Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); }
}
}
I am printing the time in this code. Its showing that, it took only 10 seconds to complete the entire process. That means all 2000 threads executed parallelly? I have heard that the number of actual threads running will be based on the number of cores in the system. But how did all 2000 threads run parallely?

The number of logical CPUs determines the number of threads running at a given moment.
However, a CPU can switch threads every 100 microseconds or about 10,000 times per second giving the illusion more threads are running at once. Calling sleep is likely to cause the CPU to context switch until after the timeout.
NOTE: System.out.println holds a lock for the output, so in reality, only one thread at a time is doing real work, and even then the program is probably being slowed down by the speed your screen will update. Try removing the println (and the sleep) and it should complete in a fraction of the time.
But how did all 2000 threads run parallely?
Almost all of them were asleep. The only busy thread was likely to be the one updating the screen with the buffered println messages.

Related

Move to main thread after another thread go to sleep

I have my main and a thread running alongside it, I want to be able to run the thread first and then move to any other thread, for example, my main.
I tried to look over google but could not find an answer.
public class AutoUpdater implements Runnable {
public void run() {
System.out.println("Thread is running...");
for (int i = 0; i < clients.size(); i++) {
do something...
}
System.out.println("Thread ended.\n");
int time = 1000 * 60 * 60 * 24;
try {
Thread.sleep(time);
} catch (InterruptedException e) {
System.out.println("Something interrputed thread while running.");
}
}
public class Main {
public static void main(String[] args) throws IOException, ClassNotFoundException {
Runnable runnable = new AutoUpdater(clients);
Thread thread = new Thread(runnable);
thread.start();
// run after the above thread finish and go to sleep
System.out.println("This is a test");
}
Like I said above I want my thread to finish and go sleep for X time, for example, 24 hours and when it goes to sleep move back to my main thread.
The goal is to make a bank system that updates all clients accounts first and then the method run (my second Thread) will go sleep for the next 24 hours. and move back my main.
What you have done in your code above created a thread that runs concurrently with the main thread. What actually happens is:
Main thread starts and initiates AutoUpdater thread
The two threads will run concurrently. In fact, the Main thread may even terminate before the AutoUpdater thread has really started.
The auto-update thread processes the clients ONCE, then sleeps for 24 hours and then terminates and your program completely terminates at this point.
So sticking with what you have, the first step is to get the AutoUpdater thread to run every 24 hours. One way you could do this is to keep the thread running and put a while loop in the run method so that it doesn't terminate but processes the clients collection every 24 hours. So now AutoUpdater might look like this:
public class AutoUpdater implements Runnable {
public void run() {
while (true) {
try {
System.out.println("Thread is running...");
for (int i = 0; i < clients.size(); i++) {
// do something...
}
} finally {
System.out.println("Thread ended.\n");
}
int time = 1000 * 60 * 60 * 24;
try {
Thread.sleep(time);
} catch (InterruptedException e) {
System.out.println("Something interrputed thread while running.");
}
}
}
}
However, the code above has some issues in that it will drift. If for example, processing takes an hour then the next time it runs will be 25 hours after the last run initial started. Fortunately, Java provides a thread executor service that will run your thread on a fixed schedule called ScheduledExecutorService. So let's unwind the while loop and introduce the executor instead.
public class AutoUpdater implements Runnable {
public void run() {
System.out.println("Thread is running...");
for (int i = 0; i < clients.size(); i++) {
// do something...
}
System.out.println("Thread ended.\n");
}
}
public static class Main {
public static void main(String[] args) throws IOException, ClassNotFoundException {
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
executor.scheduleAtFixedRate(
new AutoUpdater(clients, lock.writeLock()),
0,
24,
TimeUnit.HOURS);
System.out.println("This is a test");
}
}
Now we've got the auto-updater thread running every 24 hours from when we started the process. If you want to fix the time, i.e. at 8 AM every day you can either calculate the delay till that time (though this won't take into account daylight saving issues) or use a third-party library like Quartz to schedule at a specific time of day.
I want to be able to run the thread first and then move to any other thread, for example, my main.
Presumably by this, you mean that you want to stop other threads from executing while the Auto-Update is running. For this, you have several options available. In the first instance, you can use a monitor to synchronize and lock threads, i.e.
Object sharedMonitor = new byte[0]
// In your auto-updater and other threads
synchronised(sharedMonitor ) {
}
The syntax above will only allow a single thread to enter a synchronized block at a time for the same monitor instance. This would work fine in the example above where you only have the two threads. If you have more than the two threads it becomes problematic as you only really want the other threads to block when the auto-updater is running. In this case, this isn't the right solution for you. What you are after is something that will let all the threads run concurrently until the auto-updater needs to run and then they all need to block and wait for the auto-updater to finish. Fortunately for you, Java has a ReadWriteLock which does exactly that.
So let's add that lock and use it.
public static class Main {
private static List<String> clients = new ArrayList<>();
public static void main(String[] args) throws IOException, ClassNotFoundException {
ReadWriteLock lock = new ReentrantReadWriteLock();
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
executor.scheduleAtFixedRate(
new AutoUpdater(clients, lock.writeLock()),
0,
24,
TimeUnit.HOURS);
Lock readLock = lock.readLock();
while (true) {
try {
readLock.lock();
System.out.println("This is a test");
} finally {
readLock.unlock();
}
}
}
}
So above we have:
Added a read-write lock
Passed the write lock to AutoUpdater
Added a while loop to the main method so it doesn't terminate and can do whatever run-of-the-mill processing it is meant to be doing.
In the while loop we've acquired the read lock at the start and released it at the end.
The last piece of the puzzle is to use the write lock in AutoUpdater
public class AutoUpdater implements Runnable {
public void run() {
try {
lock.lock();
System.out.println("Thread is running...");
// do something...
}
} finally {
System.out.println("Thread ended.\n");
lock.unlock();
}
}
}

Handling the Hanging Tasks [duplicate]

This question already has answers here:
ExecutorService that interrupts tasks after a timeout
(11 answers)
Closed 7 years ago.
This is just an example to explain my problem...
I am using ExecutorService with 20 active threads and 75K max queued items...
In my case, a normal task should not take more than 10 seconds, if it takes more time that means there's some problem with the task.
If all the threads are hung due to problematic tasks my RejectionHandler would restart the entire service.
I have two questions here:
I do not like the idea of restarting the service, instead if there's
way to detect hanging thread and we could just restart that hung
thread that would be great. I have gone through couple of articles to handle hung threads with ThreadManager but have not found anything
with ExecutorService.
I am very much fascinated about the Executors.newCachedThredPool()
because on peak days we are heavily loaded with incoming tasks, and
on other days they are very few. Any suggestions would be greatly
appreciated.
public class HangingThreadTest {
// ExecutorService executorService = Executors.newCachedThreadPool()
private static ExecutorService executorService = new ThreadPoolExecutor(10,
20, 5L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(75000));
public static void main(String... arg0) {
for (int i = 0; i < 50000; i++) {
executorService.submit(new Task());
}
}
}
/**
* Task to be completed
*/
class Task implements Runnable {
private static int count = 0;
#Override
public void run() {
count++;
if (count%5 == 0) {
try {
System.out.println("Hanging Thread task that needs to be reprocessed: "
+ Thread.currentThread().getName()+" count: "+count);
Thread.sleep(11000);
} catch (InterruptedException e) {
// Do something
}
}
else{
System.out.println("Normal Thread: "
+ Thread.currentThread().getName()+" count: "+count);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
//Do something
}
}
}
}
There is no build-in mechanism in Executors framework that would help terminate a thread if it has been running for more than a threshold value.
But we can achieve this with some extra code as below:
Get the Future object returned by the executorService.submit(...);.
Future future = executorService.submit(new Task());
Call the get method on this future object to and make it wait only for threshold interval for task completion. Below, an example that is waits for only 2 secs.
try {
f.get(2, TimeUnit.SECONDS);
} catch (TimeoutException e) {
f.cancel(true);
} catch (Exception e) {}
The above code waits for 2 seconds for task completion it throws a TimeoutException if it doesn't get completed during that time. Subsequently we can call cancel method on the future object. This results in setting the interrupt flag in the thread that is executing the task.
Now the final change is, in the Task class code we need to check at necessary points (application dependent), whether the interrupt flag has been set to true using isInterrupted() method of Thread class. If interrupted==true, we can do the necessary clean up and return from the run method immediately. The critical piece here is to identify the necessary points in your Task class where you want to check for this interrupted flag.
This makes the thread available for processing next task.
You may have a look at this article, it was very helpful for me before when I was facing the same problem : Java Hanging Thread Detection

ExecutorService Execptions and memory leak?

I'm doing an optimization problem in which I want to execute each Solver thread (one at a time) with random parameters for a fixed period of time. If any of the thread successfully finds a solution, it would return and the program will exit.
I have the code below where I used an ExecutorService and Future to help me accomplish this. However, for some reason, the memory usage of the program increases linearly as time goes on, and the program will terminate with an OutOfMemory error before it gets very far. My Solver code is certainly not the issue as it has no static variables and uses a constant amount of memory. I'm wondering if it's because I'm not cleaning up the threads or handling the exceptions properly, but I can't seem to find any egregious problem from the code.
public class RandomizedSolver {
public static void main(String[] args) {
try {
for (int i = 0; i < 300; i++) {
ExecutorService executor = Executors.newSingleThreadExecutor();
try {
System.out.println("Starting new thread");
Future<Void> future = executor.submit(new Solver(args));
future.get(1, TimeUnit.SECONDS);
executor.shutdownNow();
break;
} catch (TimeoutException e) {
System.out.println("Thread timeout.");
executor.shutdownNow();
continue;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
The point of using ExecutorServices is to reuse their threads, not to keep recreating them. You should revise your design and have only one ExecutorService, with the appropriate number of underlying threads, and submit all you tasks to that unique ExecutorService.
Also note that if your tasks take more than 1 seconds and if they do not terminate promptly when interrupted, you could have up to 300 ExecutorServices and 300 Solver tasks running at the same time. Depending on how much memory you Solver takes, that could result in a OOME.

Java threads - High cpu utilization?

I have two threads. I am invoking one (the SocketThread) first and then from that one I am invoking another thread (the 'ProcessThread'). My issue is that, during the execution the CPU usage is 50%. It reduces to 0% when I add TimeUnit.NANOSECONDS.sleep(1) in the ProcessThread run method. Is this the right method to modify? Or any advice in general for reducing the CUP utilization.
Below is my code:
public class SocketThread extends Thread {
private Set<Object> setSocketOutput = new HashSet<Object>(1, 1);
private BlockingQueue<Set<Object>> bqSocketOutput;
ProcessThread pThread;
#Override
public void run() {
pThread = new ProcessThread(bqSocketOutput);
pThread.start();
for(long i=0; i<= 30000; i++) {
System.out.println("SocketThread - Testing" + i);
}
}
}
public class ProcessThread extends Thread {
public ProcessThread(BlockingQueue<Set<Object>> bqTrace) {
System.out.println("ProcessThread - Constructor");
}
#Override
public void run() {
System.out.println("ProcessThread - Exectution");
while (true) {
/*
try {
TimeUnit.NANOSECONDS.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
}
}
}
You can "reduce the CPU utilization" by sleeping threads, but that means that you are not getting any work done on those threads (or if you are, it's getting done dramatically slower than if you just let the threads run full-out). It's like saying you can reduce fuel consumption in your car by stopping every few miles and turning the engine off.
Typically a while(true) loop being run without some sort of blocking thread synchronization (like a .Wait(), or in your situation, a BlockingQueue.take() as #Martin-James suggests) is a code smell and indicates code that should be refactored.
If your worker thread waits on the blocking queue by calling take() it should not consume CPU resources.
If its in a tight loop that does nothing (as the code in the example suggests) then of course it will consume resources. Calling sleep inside a loop as a limiter probably isn't the best idea.
You have two tight loops that will hog the CPU as long there's work to be done. Sleeping is one way to slow down your application (and decrease CPU utilization) but it's rarely, if ever, the desired result.
If you insist on sleeping, you need to increase your sleep times to be at least 20 milliseconds and tune from there. You can also look into sleeping after a batch of tasks. You'll also need a similar sleep in the SocketThread print loop.

ScheduledThreadPoolExecutor with one scheduled task(Runnable) keeps reporting back job counter + 1 all the time

I get an ever increasing(like 1,2,3,4,5,6,7...) task count when I print s.getTaskCount(). I don't understand why.
public class MyTask implements Runnable
{
public void run()
{
System.out.println("whatever....");
}
}
ScheduledThreadPoolExecutor s = new ScheduledThreadPoolExecutor(3);
s.scheduleAtFixedRate(new MyTask(), 0, 10, TimeUnit.SECONDS);
while(1>0)
{
try
{
System.out.println("TASK COUNT: "+s.getTaskCount());
Thread.sleep(60000);
}
catch(InterruptedException e)
{
System.out.println(e);
}
}
ScheduledThreadPoolExecutor.getTaskCount() states in the documentation:
Returns the approximate total number
of tasks that have been scheduled for
execution. Because the states of tasks
and threads may change dynamically
during computation, the returned value
is only an approximation, but one
that does not ever decrease across
successive calls
So, getTaskCount() returns the total number of tasks that have been executed by the pool.
I'm not sure what your goal is, but if you want the number of tasks currently being executed, try getActiveCount().

Categories

Resources