How to throttle method invocations to allow threads to complete - java

I currently have the following setup. I am getting out fo memory exceptions after it runs for a little while; I suspect the for loop in main is causing too much of a backup method calls. What is the best way to throttle the calls if I don't wish to increase the thread pool size?
public class ManagedThreads {
private final static ExecutorService ex = Executors.newFixedThreadPool(10);
public static void myMethod(final int i) {
ex.execute(new Runnable() {
public void run() {
// method body using i
}
});
}
public static void main(String[] args) {
for (int i = 0; i < 1000000000; ++i)
myMethod(i);
}
}
EDIT
I meant to show that I am passing in the index for the loop to the runnables.

You have ten threads so add ten jobs and you will never run out of memory trying to schedule them.
e.g.
public class ManagedThreads {
private final static ExecutorService ex = Executors.newFixedThreadPool(10);
public static void myMethod(final int i) {
ex.execute(new Runnable() {
public void run() {
// do every tenth task.
for(int j = i; j < 1000000000; j += 10) {
// method body
}
}
});
}
public static void main(String[] args) {
for (int i = 0; i < 10; ++i)
myMethod(i);
}
}

I am getting out fo memory exceptions after it runs for a little while; I suspect the for loop in main is causing too much of a backup method calls. What is the best way to throttle the calls if I don't wish to increase the thread pool size?
This is a FAQ. See my answer here: Process Large File for HTTP Calls in Java
You need to define your own bounded job queue and then define a RejectedExecutionHandler. The following code will block when it tries to add more than 100 jobs to the job queue.
BlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(100);
ThreadPoolExecutor threadPool =
new ThreadPoolExecutor(10, 10, 0L, TimeUnit.MILLISECONDS, queue);
// we need our RejectedExecutionHandler to block if the queue is full
threadPool.setRejectedExecutionHandler(new RejectedExecutionHandler() {
#Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
try {
// this will block the producer until there's room in the queue
executor.getQueue().put(r);
} catch (InterruptedException e) {
throw new RejectedExecutionException(
"Unexpected InterruptedException", e);
}
}
});

i would go with this (it will allow each worker to perform same amount of work in terms of cpu clocks)
private final static ExecutorService ex = Executors.newFixedThreadPool(10);
final static AtomicInteger counter = new AtomicInteger(0);
public static void myMethod(final int i) {
ex.execute(new Runnable() {
public void run() {
while (counter.getAndIncrement() < 1000000000) {
//method body
}
}
});
}
public static void main(String[] args) {
for (int i = 0; i < 10; ++i)
myMethod(i);
}
}
or do increments of 10 in each worker as Peter suggested. Saves a lot of objects and processing speed is high.

Related

How to wait for one of the running threads in ExecutorService to finish to assign another task

I have loop that assign task to ExecutorService with fixed size thread, I want the main program wait for threadPool to free one of its' threads to assign another task to it.
Here is my sample code: in this sample code I want finished! be printed at end and want to use ExecutorService.
public static void main(String[] args) {
ExecutorService ex = Executors.newFixedThreadPool(3);
for(int i=0; i< 100; i++) {
ex.execute(new TestThread(i)); // I want the program wait here for at least one thread to free
}
System.out.println("finished!");
}
private static class TestThread implements Runnable {
private int i;
public TestThread(int i) {
this.i = i;
}
#Override
public void run() {
System.out.println("hi: " + i);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
I understand you want for the thread that is submitting a job, to block in the case when there is not a free, readily available worker thread in the executor service. This can be useful to apply back-pressure.
At the core the executor service is "simply" composed of a queue of runnables, and of a pool of worker threads.
You can obtain this behaviour by building an executor service with a work-queue of fixed size (in your case, size one).
In code: (note that, your caller thread will still continue after submitting the last job; it will not wait for that job to be completed)
package stackOv;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class BackPressure {
public static void main(String[] args) {
// this is the backing work queue; in this case, it is of bounded size
ArrayBlockingQueue<Runnable> q = new ArrayBlockingQueue<>(1);
ExecutorService ex = new ThreadPoolExecutor(3, 3, 30, TimeUnit.SECONDS, q,
new ThreadPoolExecutor.CallerRunsPolicy());
for(int i=0; i< 100; i++) {
ex.execute(new TestWork(i));
}
System.out.println("finished!");
}
private static class TestWork implements Runnable {
private int i;
public TestWork(int i) {
this.i = i;
}
#Override
public void run() {
System.out.println("hi: " + i);
try {
Thread.sleep(100);
} catch (InterruptedException e) { e.printStackTrace(); }
}
}
}
All you need is:
ex.awaitTermination();

Loop in multiple Threads

right now i'm trying to get my head arround threads and concurrency,
so i tried to make multiple threads which counts together to 1000.
Example: Thread 1=0, Thread 2=1.Thread 3=2, and so on
As you will see in the code i implemented the Runnable interface and started the threads.
What i can see is that every thread starts the loop only for itself even if i use a synchronized method.
This is the loop "class"
private String threadname;
private int counter;
Task3(String threadname,int counter) {
this.threadname = threadname;
this.counter =counter;
}
private synchronized void compute(int i) {
try {
// "simulate" computation
System.out.println(threadname);
Thread.sleep(100);
System.out.println(" " + i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void run() {
for(int i=0; i <= counter;i++)
compute(i);
}
and in this class i start 4 threads with a for loop and give the method aboce the parameters which is only the thread name and how often they should count...
for(int i=0; i<=3;i++){
Runnable r =new Thread(new Task3("Thread"+i,1000));
Thread t = new Thread(r);
t.start();
}
thanks in advance
Explanation
Synchronized only means that it is ensured that a thread waits before entering the method until another thread has finished executing this method. This means that only one thread, at one time, can be inside of this synchronized method.
This can prevent strange behavior when using non-atomic operations. For example threads catching outdated values, thinking they would be up-to-date.
Solution
If you want that all threads count together you need some kind of shared resource, i.e. the counter. Currently every thread has his own counter. You need one counter in total which is shared among all threads.
A quick and dirty method would be to make the counter static. But you can probably do better with a design like this:
Class which manages the threads:
public class Demo {
public static void main(String[] args) {
Demo demo = new Demo();
for (int i = 0; i < 3; i++) {
Counter counter = new Counter(demo, 1000);
counter.start();
}
}
// Provide a shared resource for all threads
private int sharedCounter = 0;
// Provide a count method for all threads
// which is synchronized to ensure that no
// strange behavior with non-atomic operations occurs
public synchronized void count() {
sharedCounter++;
}
}
And the Thread class:
public class Counter extends Thread {
private Demo mDemo;
private int mAmount;
public Counter(Demo demo, int amount) {
// Remember the shared resource
mDemo = demo;
mAmount = amount;
}
#Override
public void run() {
for (int i < 0; i < mAmount; i++) {
// Call the count method provided
// by the shared resource
mDemo.count();
// Sleep some millis
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

Impact of one synchronized from another synchronized method in multi-thread environment?

I am working with the synchronization threads where I have three synchronized method and each method will access by individual thread (Total 3 threads in current program )
In our program we are calling one syn method is calling another sync method, below is sample code which is inspired from real application :
public class ThreadTest {
public static synchronized void suncMessage() {
System.out.print("1");
}
public static synchronized void suncMessage2() {
suncMessage();
System.out.print("2");
}
public static synchronized void suncMessage3(String s) {
System.out.print("3m" + s);
}
public static void main(String... at) throws InterruptedException {
Thread t1 = new Thread() {
public void run() {
for (int i = 0; i <= 2; i++) {
suncMessage();
}
}
};
Thread t2 = new Thread() {
public void run() {
for (int i = 0; i <= 2; i++) {
suncMessage2();
}
}
};
Thread t3 = new Thread() {
public void run() {
for (int i = 0; i <= 2; i++) {
suncMessage3("3");
}
}
};
t1.start();
t2.start();
t3.start();
}
}
So my question is, what is impact of calling one synch. method from another synch.?? Is it good practices and how it will impact the complexity of program?
Nice question, but you have to try hard when you are working on this type of scenarios and the performance may effect. Because synchronization is approx 50 time slower than normal method.

Multithreading example for x number of threads

I am new to Multithreading world, I am not sure how should I write a java application that can invoke x number of threads, if we pass x number of threads from the command prompt. Just Like if we are passing
java –jar pds_client_batch.jar <number of threads>
and here if number of threads is passed as 20 then it should run for twenty threads. Any simple example will be appreciated.
public class Example
{
private class DumbThread implements Runnable
{
public void run()
{
System.out.println("Thread ran");
}
}
public static void main(String args[])
{
int input = Integer.parseInt(args[0]);
for (int x = 0; x < input; x++)
new Thread(new DumbThread()).start();
}
}
Now, if you want it to do something useful...
Edit: made more complete. It still does nothing useful. Also it doesn't do even basic error checking.
You could also you an executorService like ThreadPoolExecutor. and pass in the number of threads you want it to use.
Nowadays you are encouraged to use thread pools for better management of threads. You can create a fixed thread pool:
class ThreadTask implements Runnable {
private int id;
public ThreadTask(int id) {
this.id = id;
}
public void run() {
System.out.println("I am task " + id);
}
}
public class TestPool {
public static void main(String[] args) {
int size = Integer.parseInt(args[0]);
// create thread pool with given size
ExecutorService service = Executors.newFixedThreadPool(size);
// queue some tasks
for(int i = 0; i < 3 * size; i++) {
service.submit(new ThreadTask(i));
}
// wait for termination
service.shutdown();
service.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
}
}

Single threading a task without queuing further requests

I have a requirement for a task to be executed asynchronously while discarding any further requests until the task is finished.
Synchronizing the method just queues up the tasks and doesn't skip. I initially thought to use a SingleThreadExecutor but that queues up tasks as well. I then looked at the ThreadPoolExecutor but it reads the queue to get the task to be executed and therefore will have one task executing and a minimum of one task queued (the others can be discarded using ThreadPoolExecutor.DiscardPolicy).
The only thing I can think off is to use a Semaphore to block the queue. I've come with the following example to show what I'm trying to achieve. Is there a simpler way? Have I missed something obvious?
import java.util.concurrent.*;
public class ThreadPoolTester {
private static ExecutorService executor = Executors.newSingleThreadExecutor();
private static Semaphore processEntry = new Semaphore(1);
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 20; i++) {
kickOffEntry(i);
Thread.sleep(200);
}
executor.shutdown();
}
private static void kickOffEntry(final int index) {
if (!processEntry.tryAcquire()) return;
executor.
submit(
new Callable<Void>() {
public Void call() throws InterruptedException {
try {
System.out.println("start " + index);
Thread.sleep(1000); // pretend to do work
System.out.println("stop " + index);
return null;
} finally {
processEntry.release();
}
}
}
);
}
}
Sample output
start 0
stop 0
start 5
stop 5
start 10
stop 10
start 15
stop 15
Taking axtavt's answer and transforming the above example gives the following simpler solution.
import java.util.concurrent.*;
public class SyncQueueTester {
private static ExecutorService executor = new ThreadPoolExecutor(1, 1,
1000, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(),
new ThreadPoolExecutor.DiscardPolicy());
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 20; i++) {
kickOffEntry(i);
Thread.sleep(200);
}
executor.shutdown();
}
private static void kickOffEntry(final int index) {
executor.
submit(
new Callable<Void>() {
public Void call() throws InterruptedException {
System.out.println("start " + index);
Thread.sleep(1000); // pretend to do work
System.out.println("stop " + index);
return null;
}
}
);
}
}
It looks like executor backed by SynchronousQueue with desired policy does what you want:
executor = new ThreadPoolExecutor(
1, 1,
1000, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(),
new ThreadPoolExecutor.DiscardPolicy());
if there is no queue, there is no need for an executor i'd say. using a semaphore alone seems enough. i'm using the code below to avoid running the same code when it is already running. just make sure the semaphore is static volatile, which makes the semaphore the only semaphore for the class and propagates the semaphore reference to other threads' heap as soon as it is changed
if (this.getSemaphore().tryAcquire()) {
try {
process();
} catch (Exception e) {
} finally {
this.getSemaphore().release();
}
}
else {
logger.info(">>>>> Job already running, skipping go");
}

Categories