My requirement is to restrict the number of threads which uses my service at any point in time. Executor service is not helping me here as my problem space is little different. Let me explain with an example.
I have exposed a REST API which does one job. On the fly, my controller invokes one of the services for the job execution. But I have to make sure only 'n' threads access the service. That means threads/API-access will be continuously growing but at some place, I have to keep them in waiting if 'n' threads are already using the service. And the end of the execution I should get the response from the service and returns back to the endpoint and then to the client.
If I use FutureTask and callable, how and where will I write the .get() method? Because my threads will be continuously growing in number and dynamic in nature.
Hope the problem statement is clear, let me know if more clarification required.
If you just want to restrict the max number of threads which can access your service, then you might use Bounded Semaphore and can provide the max number of permits.
Here is the sample code (assuming that your service is singleton) :-
public class SampleService {
private Semaphore semaphore = new Semaphore(n, true);
public void someMothod() {
try {
semaphore.acquire();
// execute the task
} catch (InterruptedException e) {
} finally {
semaphore.release();
}
}
}
You have to make sure that only one instance of semaphore is created. If you can have multiple instances of your service in the application, then make semaphore static.
private static Semaphore semaphore = new Semaphore(n, true);
You can use ExecutorCompletionService for this.
Just create an ExecutorService with fixed no of threads as stated below
ExecutorService pool = Executors.newFixedThreadPool(5);
Now create an ExecutorCompletionService using this ExecutorService.
ExecutorCompletionService completionService = new ExecutorCompletionService(pool);
Then after submitting your task you can iterate and get the future and the job result from the future as well. This won't block the thread as being done when you use Future returned from just an ExecutorService.
for(int i = 0; i < worker size ; i++) {
Future future = completionService.take();
Object content = future.get();
}
Related
I currently have a bunch of tasks that I want to execute. I am using the single-threaded executor in java. These are mainly of 2 types. Let's call these types TaskA and TaskB. I have 10 tasks of type TaskA and 5 tasks of type TaskB. I have to execute them all but I cannot control the sequence in which they are submitted to the executor. A few tasks of type TaskB might be submitted to the executor before all 10 tasks of type TaskA have been submitted. Is there any way to ensure that all 10 tasks of type TaskA are executed before the 5 tasks of type TaskB? In order to successfully execute all tasks of type TaskB, I need to first execute all tasks of type TaskA. You may think of TaskA tasks to be responsible for data loading and TaskB tasks for data processing. Without loading the data I cannot process it and run into exceptions
Please do let me know if I can phrase the question better if it is unclear
No, the default executor service implementations do not differentiate between submitted tasks.
You need a task manager object.
Define a class that contains the single-threaded executor service as a member field. That class offers methods submit( TaskA ta ) and submit( TaskB tb ).
The second method collects the B tasks, as a queue, holding them for now if we’ve not yet processed ten A tasks.
The first method accepts each A task, submitting to the executor service immediately. And the first method counts those submissions. On the tenth A task, flag is set, and all stored B tasks are submitted to the member field executor service.
The second method always checks for that “A tasks done” flag being set. If set, any further B tasks submissions are sent directly to the executor service.
Your task manager class could itself implement the ExecutorService interface. But I don’t know if I would go that far.
The way I think you could do this is using the semaphore/locking pattern.
first, you need a lock. You can use an object
Object lock = new Object();
Then you need a count of how many A tasks have completed.
int completedAs = 0; // variable name is completed 'A's, not 'as'
Both of these should be static or otherwise available to TaskA and TaskB. Then what you can do is only add the TaskB's to the ExecutorService when the appropriate number of TaskA's have completed, like
for (TaskB : allTaskBs) {
synchronized(lock) {
//add the taskB to the ExecutorService
}
}
And then upon taskA completion:
synchronized(lock) {
completedAs++;
if (...) {
lock.notify(); // you can call this multiple times to release multiple B's
}
}
Here is something of a weird solution. Provided you have a default executor.
ExecutorService service = Executors.newSingleThreadExecutor();
Your need to keep track of how many a tasks have completed and how many need to be completed.
AtomicInteger a = new AtomicInteger(0);
int totalA = 10;
Then for submitting a task.
void submitTask(Runnable t){
Runnable r = ()->{
if( t instance of TaskA ){
try{
t.run();
} finally{
a.incrementAndGet();
}
} else if( t instance of TaskB ){
if( a.get() >= totalA ){
t.run();
} else{
service.submit(this);
}
} else{
throw new RuntimeException("not an acceptable task!");
}
}
service.submit(r);
}
This will filter the TaskA's and the TaskB's, TaskA's will be immediately executed, but TaskB's will be resubmitted.
There are some flaws to this design. I think ThreadPoolExecutor can be setup a little better where you reject a task if it is not ready to be run.
I suspect that you could design your setup a little better. They have tools like an ExecutionCompletionService, or CountDownLatch that are made for creating barriers to execution.
I'm implementing a Java Data-logger which reads, at precise intervals of time, some datas from different production machines. To avoid having one call blocking the following ones, I was thinking of making a new thread for every call to the parser class.
However, this would require the creation of many threads, and then to stop them, every 10 seconds (which is my reading interval). A non-concurrent approach would cause me to have many delays when the parser gets an exception (due to the possible timeouts of the IoT devices i'm using) making the next calls to be delayed.
while(!error){
//JDBC connections and other calls here
//Queryresult is a ResultSet that returns all the machine addresses needing to be read
while(queryresult.next()){
//Parser.ParseSpeedV is the method I need to call concurrently
Double v = Parser.ParseSpeedV(..Params..);
Double s = v*queryresult.getDouble("const");
st = conn.createStatement();
st.executeUpdate("INSERT INTO ...");
}
st.close();
Thread.sleep(10000);
}
What is the best way to achieve a concurrent method calls (to the method ParseSpeedV) without having the overhead caused by thousands of thread starting every day?
What you want to use is a ScheduledExecutorService. It allows you to add tasks that are repeated at a fixed rate or fixed delay. So you can i.E. add a task that fetches data from a device every 10 seconds. The Executor service then makes sure that it is run in that interval with resonably low deviation.
final ScheduledExecutorService myScheduledExecutor = Executors.newScheduledThreadPool(16);
myScheduledExecutor.scheduleAtFixedRate(myTask, 0L, 10L, TimeUnit.SECONDS);
Your situation is the perfect use case for a Thread Pool. This part of Java's library that's built on top of simple Threads and allows you to create a fixed-sized pool of threads and reuse them over and over:
ExecutorService executor = Executors.newFixedThreadPool(5);
Any time you want to do some work you add it to the executor
executor.execute(new Runnable() {
#Override
public void run() {
// Do some work
}
});
If you call execute more than 5 times, the extra runnables are held in a queue until there's room.
Now, if you need to receive information from these runnning tasks, you need to write a class that implements Runnable and accepts some kind of object that wishes to have the information that your runnable has:
public class Worker implements Runnable {
Consumer consumer;
public Worker(Consumer consumer) {
this.consumer = consumer;
}
#Override public void run() {
// Do work
value = // get value
consumer.put(value);
}
}
Now all you have to do is define a Consumer class that operates on the value (has that put() method, or whatever) and create your Workers like this:
Consumer consumer = new Consumer();
Worker worker = new Worker(myConsumer);
executor.execute(worker);
I'm doing a download application for android. The downloading part is now successfully implemented and its working.
What I need is to download the file parallel in segments. To be more clear, if the user specify 8 segments, I want to create 8 Threads and do the downloading.
So in what way will I be able to create 8 threads dynamically? Also as I'm doing this for an phone how will I be able to maintain the memory consumption at a minimum level?
I have not worked with threads before, so I hope you can help me with this. Thank you for your time! :)
The most efficient way to create a fixed number of threads is to use the ExecutorService:
ExecutorService exec = Executors.newFixedThreadPool(8);
It's basically a fixed-size thread pool that takes a lot of the management burden from the developer.
Edit: So your flow should be something like this:
First, define your thread task class (each thread will execute the call method of its own task):
class ThreadTask implements Callable<Object> {
public Object call() {
// execute download
...
return result;
}
}
If you want to pass any parameters to the tasks, put some private fields in the class above and pass them through a constructor. Also, you can return any type from call, just change the type in the implements Callable<...> part.
When you want to fire off the threads, create the pool and submit the tasks:
ExecutorService exec = Executors.newFixedThreadPool(8);
List<Future<Object>> results = new ArrayList<Future<Object>>();
// submit tasks
for(int i = 0; i < 8; i++) {
results.add(exec.submit(new ThreadTask()));
}
...
// stop the pool from accepting new tasks
exec.shutdown();
// wait for results
for(Future<Object> result: results) {
Object obj = result.get();
}
Take a look at ExecutorService, in particular Executors.newFixedThreadPool(int i), this is an excellent way to handle threads in a system friendly matter.
Please look at my following code....
private static final int NTHREDS = 10;
ExecutorService executor = Executors.newFixedThreadPool(NTHREDS);
while(rs.next()){
webLink=rs.getString(1);
FirstName=rs.getString(2);
MiddleName=rs.getString(3);
Runnable worker = new MyRunnable(webLink,FirstName,MiddleName);// this interface has run method....
executor.execute(worker);
}
//added
public class MyRunnable implements Runnable {
MyRunnable(String webLink,String FirstName,String MiddleName){
** Assigning Values...***
}
#Override
public void run() {
long sum = 0;
**Calling method to crawl by passing those Values**
try {
Thread.sleep(200);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
In this part if the resultset(rs) having 100 records excutor creating 100 threads..... I need to run this process with in 10 threads. I need your help to know how to get control of threads.. If any thread has completed its task then it should process the immediate available task from the Result Set. Is it possible to achieve using executor framework.
Thanks...
vijay365
The code you've already posted does this. Your code will not immediately spawn 100 threads. It will spawn 10 threads that consume tasks from a queue containing your Runnables.
From the Executors.newFixedThreadPool Javadocs:
Creates a thread pool that reuses a
fixed set of threads operating off a
shared unbounded queue.
Instead of using a static number of threads (10 in this case) you should determine the number dynamically:
final int NTHREADS = Runtime.getRuntime().availableProcessors();
Also, I don't get why you are calling Thread.sleep?
ResultSet is probably a JDBC query result.
This design is almost certain to be doomed to failure.
The JDBC interface implementations are not thread-safe.
ResultSets are scare resources that should be closed in the same scope in which they were created. If you pass them around, you're asking for trouble.
Multi-threaded code is hard to write well and even harder to debug if incorrect.
You are almost certainly headed in the wrong direction with this design. I'd bet a large sum of money that you're guilty of premature optimization. You are hoping that multiple threads will make your code faster, but what will happen is ten threads time slicing on one CPU and taking the same time or longer. (Context switching takes time, too.)
A slightly better idea would be to load the ResultSet into an object or collection, close the ResultSet, and then do some multi-threaded processing on that returned object.
Try executor.submit(worker);
We have 1000 threads that hit a web service and time how long the call takes. We wish for each thread to return their own timing result to the main application, so that various statistics can be recorded.
Please note that various tools were considered for this, but for various reasons we need to write our own.
What would be the best way for each thread to return the timing - we have considered two options so far :-
1. once a thread has its timing result it calls a singleton that provides a synchronised method to write to the file. This ensures that all each thread will write to the file in turn (although in an undetermined order - which is fine), and since the call is done after the timing results have been taken by the thread, then being blocked waiting to write is not really an issue. When all threads have completed, the main application can then read the file to generate the statistics.
2. Using the Executor, Callable and Future interfaces
Which would be the best way, or are there any other better ways ?
Thanks very much in advance
Paul
Use the latter method.
Your workers implement Callable. You then submit them to a threadpool, and get a Future instance for each.
Then just call get() on the Futures to get the results of the calculations.
import java.util.*;
import java.util.concurrent.*;
public class WebServiceTester {
public static class Tester
implements Callable {
public Integer call() {
Integer start = now();
//Do your test here
Integer end = now();
return end - start;
}
}
public static void main(String args[]) throws Exception {
ExecutorService pool = Executors.newFixedThreadPool(1000);
Set<Future<Integer>> set = new HashSet<Future<Integer>>();
for (int i =0 ; i < 1000 i++) {
set.add(pool.submit(new Tester()));
}
Set<Integer> results = new Set<Integer>();
for (Future<Integer> future : set) {
results.put(future.get());
}
//Manipulate results however you wish....
}
}
Another possible solution I can think of would be to use a CountDownLatch (from the java concurrency packages), each thread decrementing it (flagging they are finished), then once all complete (and the CountDownLatch reaches 0) your main thread can happily go through them all, asking them what their time was.
The executor framework can be implemented here. The time processing can be done by the Callable object. The Future can help you identify if the thread has completed processing.
You could pass an ArrayBlockingQueue to the threads to report their results to. You could then have a file writing thread that takes from the queue to write to the file.