java callback functions in a multi threaded environment - java

In AJAX, suppose i submit a request asynchronously. When the reposne returns , it executes a callback function.
What is the best way to implement the same in a java multithreaded environment?
i.e Main thread creates a child thread and submits a task and then the child thread returns a callback function needs to be executed by the main thread.
Is this possible? In main thread I can do wait() and in child thread i can do notify() but in that case the main thread will wait until the child thread finishes.
But in AJAX the main thread continues its operation...that is what i want

You could use an ExecutorService to do tasks on the background and then use the methods of the Future you get back to wait for the result. For example:
class Main {
private static final ExecutorService es = Executors.newCachedThreadPool();
public static void main(final String... args) throws Throwable {
List<Future<Integer>> results = new ArrayList<>();
for (int i = 0; i < 10; i++) {
results.add(asyncSum(i, i*i));
}
// here, in the main thread, you can do whatever you want
// while the calculations are performed in background threads
// ...
// after the main thread finishes what it was doing, it
// can process the futures
for (final Future<Integer> result : results) {
System.out.println(result.get());
}
}
// this method launches a calculation on a worker thread and immediately
// returns a Future, which is a reference to the result of the calculation
// once it is completed
private static Future<Integer> asyncSum(final int a, final int b) {
return es.submit(new Callable<Integer>() {
#Override public Integer call() throws Exception {
return a + b;
}
});
}
}
In the example above, the main thread will block until the first computation is done, then print it. Then block until the second computation is done, then print it, etc.
If you wish to print the results as they become available (in an unspecified order), then you could use a CompletionService, and instead of having a list of results and iterating on it, you'd get your futures from the CompletionService itself through its .take() method, that blocks until a computation is finished, or .poll(), which returns a Future if there there are finished computations, or null if there are no computations finished -- this way your main thread will never block.
The following example uses a CompletionService. It shows a main thread that never blocks, uses background threads to do calculations and process the results as they become available:
class Main {
public static void main(String[] args) throws Throwable {
final ExecutorService es = Executors.newCachedThreadPool();
final CompletionService<Integer> cs = new ExecutorCompletionService<>(es);
submitSomeCalculations(cs);
while (true) {
doMainThreadWork();
processFinishedCalculations(cs);
}
}
private static void submitSomeCalculations(final CompletionService<Integer> cs) {
for (int i = 0; i < 10; i++) {
submitAsyncSum(cs, i, i * i);
}
}
private static void submitAsyncSum(final CompletionService<Integer> cs, final int a, final int b) {
cs.submit(new Callable<Integer>() {
#Override public Integer call() throws Exception {
Thread.sleep(100 + (long) (Math.random() * 900));
return a + b;
}
});
}
private static void processFinishedCalculations(final CompletionService<Integer> cs) throws ExecutionException, InterruptedException {
while (true) {
final Future<Integer> result = cs.poll();
if (result == null) {
System.out.println("> no finished results...");
break;
} else {
System.out.println("> result available: " + result.get());
}
}
}
static void doMainThreadWork() {
System.out.println("work from main thread...");
}
}

Related

Custom thread pool implementation in java

For leaning purpose i am trying to implement my own thread pool in java. Below is what i have implemented. I have few questions about this implementation:
Although i am using BlockingQueue like built in java Executors expect us to provide Runnable objects (through execute method). But in my case i feel like i can create any object instead of Runnable. So then why does Java executors expect Runnable, i tried looking into the source code but could not figure it out yet.
Is there anything else wrong with this primitive implementation ?
Please find the code.
public class CustomThreadPool {
private final BlockingQueue<Runnable> blockingQueue;
private final Worker[] workers;
public CustomThreadPool(final int numOfThreads) {
blockingQueue = new LinkedBlockingQueue<>();
workers = new Worker[numOfThreads];
for (int i = 0; i < numOfThreads; i++) {
workers[i] = new Worker();
workers[i].start();
}
}
public void execute(final Runnable task) {
blockingQueue.add(task);
}
public void shutdownImmediately() {
for (int i = 0; i < workers.length; i++) {
workers[i].shutdownSignal = true;
workers[i] = null;
}
}
private class Worker extends Thread {
private Runnable taskToPerform = null;
boolean shutdownSignal = false;
#Override
public void run() {
while(true && !shutdownSignal) {
taskToPerform = blockingQueue.poll();
if (taskToPerform != null) {
taskToPerform.run();
}
if(shutdownSignal) {
break;
}
}
}
}
public static void main(String[] args) throws Exception {
final CustomThreadPool threadPool = new CustomThreadPool(5);
for (int i = 0; i < 20; i++) {
threadPool.execute(() -> System.out.println(Thread.currentThread().getName()));
}
Thread.sleep(1*1000);
threadPool.shutdownImmediately();
}
}
Executor expects Runnable or Callable because it will call run or call method of these interfaces when it is running the tasks you submitted.
In Your implementation You don't use blocking aspects of BlockingQueue. Your thread pool threads will spin constantly(take cpu time) on Your while(true && !shutdownSignal) loop when there is no task exists in Your queue. Because poll() method is not blocking. And this not something You would want when implementing a thread pool.
You should use one of the blocking methods instead of poll().
You can use poll(long timeout,TimeUnit unit) method which takes time out parameter. In this case if You call Your shutdownImmediately method while any thread pool thread waiting on this call. They will wait for the time out duration and poll will return null to them They will see shutdownSignal is being set and get out of the loop. You can also call interrupt method If You don't want them to wait for the timeout.
// in run method
try {
taskToPerform = blockingQueue.poll(5, TimeUnit.SECONDS);
} catch (InterruptedException e) {
break; // this thread is interrupted. Time to leave this loop
}
// in shutdownImmediately method
workers[i].shutdownSignal = true;
// If You don't call interrupt, Threads will wait at max 5 sec for this case.
workers[i].interrupt();
workers[i] = null;
Or You can use take() method which blocks when there is nothing on the queue. But in this case You have to interrupt the threads that might be waiting on the take method call when You call Your shutdownImmediately method. Otherwise they will stuck at the take() call.
// in run method
try {
taskToPerform = blockingQueue.take();
} catch (InterruptedException e) {
break; // this thread is interrupted. Time to leave this loop
}
// in shutdownImmediately method
workers[i].shutdownSignal = true;
workers[i].interrupt(); // this is crucial for this case
workers[i] = null;

How do I get my threads to run in an orderly sequence?

I'm learning Java threads and want my code to output threads 0-9 in sequential order. I used the synchronized keyword but I don't get the results I expect.
What should I do to correct my code?
public class MyThread extends Thread {
private static final int threadMax = 10;
private static int runCount = 0;
public void printThread() {
synchronized (this) {
while (runCount++ < 100) {
System.out.println(runCount + ": " + Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public void run() {
printThread();
}
public static void main(String[] args) {
for (int i = 0; i < threadMax; i++) {
new MyThread().start();
}
}
}
It is not working as every time you are creating new MyThread object and you are synchronized over that new object. So, every Thread you created will get a lock on the diffrent object. So, you should pass a common object to take the lock like below.
class MyThread extends Thread {
private static int runCount = 0;
Object lock;
public MyThread(Object lock) {
this.lock = lock;
}
public void printThread() {
synchronized (lock) {
// your code here
}
}
//.........
}
And then call it like :
Object lock = new Object();
for (int i = 0; i < threadMax; i++) {
new MyThread(lock).start();
}
However, the above program will not ensure you that it will run in sequence. There are several ways to do that. You can use wait() and notify() to achieve your goal. Refer the below example :
public void printThread() {
while (runCount < 90) {
synchronized (lock) {
while (runCount % 10 != remainder) {
try {
lock.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(runCount + ": " + Thread.currentThread().getName());
runCount++;
lock.notifyAll();
}
}
}
And call the thread like :
Object lock = new Object();
for (int i = 0; i < 10; i++) {
new MyThread(lock, i).start();
}
You are synchronizing the context of the thread, which is different for each one. You should put into the synchronized key any common object for all diferent threads. This won't make them run in any certain secuence, just to wait each other to end.
If you want to test the synchronized keyword for any purpose, you could pass the constructor a common variable and use it in every thread:
public class MyThread extends Thread {
private static final int threadMax = 10;
private static int runCount = 0;
private Object test; //Object pointing main method
public MyThread(Object test){
this.test = test; //This won't copy values as it is an object and not a number, string...
}
public void printThread() {
synchronized (test) { //Same object for all threads
while (runCount++ < 100) {
System.out.println(runCount + ": " + Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public void run() {
printThread();
}
public static void main(String[] args) {
Object test; //common object
for (int i = 0; i < threadMax; i++) {
new MyThread(test).start();
}
}
}
If you want also to make them start in order, you should "synchronize" the loop making wait and notify calls.
Anyway, the point about multithreading is to have several threads running at the "same" time and not in sequence, as that would be the same as a linear execution.
You have several tasks that you want to delegate to threads but have them executed sequentially.
As others have pointed out, wait & notify can help you achieve that : wait until Nth have finished then notify the next. However, if you wait/notify inside your printThread method, as all your threads are waiting simultaneously on the same lock, there is no guaranties that N+1th thread will be next. So you may have
1: thread-1
...
10: thread-1
11: thread-5
...
20: thread-5
21: thread-2
...
If that's ok for you, you're done. However, in a situation where you specifically want your threads to be ordered, what you need is a waiting queue (FIFO : First In First Out).
To achieve that, you can use the awesome ExecutorService. Be aware however that they hide the Threads from you and picking that solution should not be at the cost of understanding the basics of them beforehand.
An ExecutorService is a very convenient class that can receive tasks (in the form of a Runnable, see below) and will execute them in separate Threads.
Here, I'm using a SingleThreadExecutor which execute the submitted tasks sequentially. So all you have to do is call it's execute method with your tasks as arguments, and the ExecutorService will run them in the right order, one after the other.
Here's what you can do with a few notes :
public class ThreadRunner {
// Note : Constants are usually all uppercase in Java
private static final int MAX_THREADS = 10;
private final int threadName;
public ThreadRunner(int threadName) {
this.threadName = threadName;
}
public void printThread() {
// Note: For loops are better than while when you already know the number of iterations
for (int runCount = 0; runCount < 10; runCount++) {
System.out.println(runCount + "th run from thread " + threadName);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args) {
ExecutorService executorService = Executors.newSingleThreadExecutor();
for (int i = 0; i < MAX_THREADS; i++) {
int threadName = i + 1;
// Submit a task to the executor
executorService.execute(() -> new ThreadRunner(threadName).printThread());
}
// Nicely ask for the executor to shutdown.
// Then wait for already submitted tasks to terminate.
executorService.shutdown();
try {
executorService.awaitTermination(120, TimeUnit.SECONDS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I changed a few details, here are the reasons :
Thread creation : don't inherit from Thread
I would advise you not to inherit from Thread, but create a local instance of it, as all you need is to use a Thread ; you don't want to be a Thread :
public static void main(String[] args) {
// Using Java 1.8+ lambda
Thread lambdaThread = new Thread(() -> System.out.println("Hello from a lambda in a Thread"));
lambdaThread.start();
// Using an anonymous class for java <1.8
Thread anonClassThread = new Thread(new Runnable() {
#Override
public void run() {
System.out.println("Hello from an anonymous class in a Thread");
}
});
anonClassThread.start();
}
You're creating a new Thread passing a Runnable as constructor argument, using either lambda or anonymous class, depending of your Java version.
A Runnable is simply a portion of code that will be executed (by a Thread, in this case).
Same apply to ExecutorService, it's execute methode takes a Runnable which I've created through lambdas.
Sharing static counter between threads
Your line private static int runCount = 0; is a static field, which means it is shared by all instances of the class MyThread. When you increase it in a thread, all threads will read (and write) to the same variable.
If your threads were running sequentially, the first would do it's 100 iterations, then when the second thread starts, runCount is already at 100 and you're not entering your while loop. If that wasn't intended, it may be confusing when you'll test your code.
Based on your expected output in a comment, I believe you want your threads to do 10 iterations each, not share a pool of 100 iterations and manage somehow to have each of them only perform 10.
Having the name of the thread belong to each ThreadRunner
Small detail here : previously, you were creating 10 threads. Here, the ExecutorService only creates one that he reuse for each task you submit. So Thread.currentThread().getName() would always be thread-1.
You wouldn't be able to see which task is running without this field.
If each task is started after the previous, you don't need 10 Threads, but a single Thread performing the 10 tasks sequentially.
I've been as complete as possible, but some points might be a little bit tricky, so don't hesitate to ask for clarifications!

How to terminate all other running threads after any of one thread is finish

Problem: I have collection of threads start in a loop parallelly. After exiting anyone of thread first ,all other running threads must be terminated. This is what I tried but it doesn't work. Any help is appreciated.
public class ThreadsMain {
public static void main(String[] args) {
int SIZE = 3;
Thread t[] = new Thread[SIZE];
for (int i = 0; i < SIZE; i++) {
myThreads th = new myThreads();
t[i] = new Thread(th);
t[i].start();
}
}
}
Here is one way to do it, with a synchronizer implemented with intrinsic locks, and using interruption to cancel the unfinished tasks. The data structure makes a consumer thread block until a producer has submitted a result, then it cancels the other worker threads.
This is a toy example, see the link at the end for the real-world way to do this.
First, here's a threadsafe data structure that accepts results, it allows threads to register as listeners and interrupts them once it has a result submitted to it:
class MyQueue<T> {
private java.util.List<T> results = new java.util.ArrayList<T>();
private java.util.List<Thread> listeners = new java.util.ArrayList<Thread>();
public synchronized void put(T o) {
results.add(o);
notifyAll();
for (Thread listener : listeners) {
listener.interrupt();
}
}
public synchronized T take() throws InterruptedException {
while (results.size() == 0) {
wait();
}
return results.remove(0);
}
public synchronized void addListener(Thread t) {
listeners.add(t);
}
}
(I don't like having this class know so much about the listeners but I don't want to overthink a toy example either.)
The wait method releases the lock and makes the calling thread go dormant until a notification occurs (or it can just stop waiting arbitrarily). It uses the size property of the results list to know when a result has been submitted. It's not safe to assume that because a thread stopped waiting that you can infer something about the current state, once the thread reacquires the lock it needs to check what the current state actually is. For more about how wait works see this tutorial.
Here's a task that calculates a result (sleeping between iterations just so these threads can run for a while):
class FibTask implements Runnable {
private final MyQueue<BigInteger> queue;
private final int n;
private long sleepTime;
public FibTask(int n, long sleepTime, MyQueue<BigInteger> queue) {
this.n = n;
this.sleepTime = sleepTime;
this.queue = queue;
}
#Override public void run() {
BigInteger a = BigInteger.valueOf(0);
BigInteger b = BigInteger.valueOf(1);
int i = 0;
try {
while (!Thread.currentThread().isInterrupted() && i < n) {
i = i + 1;
BigInteger temp = a;
a = b;
b = a.add(temp);
Thread.sleep(sleepTime);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
if (!Thread.currentThread().isInterrupted()) {
queue.put(b);
}
}
}
Notice in the code above how the Runnable needs to be aware of attempts to interrupt it. Interruption is cooperative, the task is responsible for deciding when to detect interruption and for handling the termination process.
Also if a task involves IO then in some cases interruption doesn't work and you have to close the socket, see this article for more discussion of this.
Here's the main program that runs the threads and gets the result. The MyQueue class is already doing most of the work so this doesn't have to do much:
class Completion {
public static void main(String ... args) throws Exception {
MyQueue<BigInteger> queue = new MyQueue<BigInteger>();
Thread t1 = new Thread(new FibTask(10, 1000L, queue));
Thread t2 = new Thread(new FibTask(20, 10000L, queue));
Thread t3 = new Thread(new FibTask(25, 50000L, queue));
queue.addListener(t1);
queue.addListener(t2);
queue.addListener(t3);
t1.start();
t2.start();
t3.start();
System.out.println(queue.take());
}
}
Be aware this isn't a fair race because of how the threads' starts are staggered, later threads are at a disadvantage. Submitting tasks to an Executor that initializes a threadpool up front would make sure that the time to start a thread didn't cause a delay here.
For a better way that makes use of java.util.concurrent features like Executors and Futures, see the example given in the API documentation for ExecutorCompletionService.
A simple approach, use a synchronized class to handle the loop condition:
class ThreadHandler
{
static Object lock = new Object();
static boolean finished = false;
static void finishThreads()
{
synchronized(lock)
{
finished = true;
}
}
static boolean isFinished()
{
boolean result;
synchronized(lock)
{
result = finished;
}
return result;
}
}
And in your runnable
class myThreads implements Runnable
{
#Override
public void run()
{
while(!ThreadHandler.isFinished())
{
}
}
}

Regarding creating synchronization mechanism [duplicate]

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
Testing a multithreaded Java class that runs the threads sequentially
Please don't treat this below question as a duplicate one..!
I have developed a class that lets multi-threads to run sequentially, one at a time and in order. All the application code between this class' claimAccess function and release Access function will be executed only in one thread at one time. All other threads will wait in the queue until the previous thread completed.Please advise I want to test my class by writing a piece of code in main() method itself .
import java.util.ArrayList;
import java.util.List;
public class AccessGate {
protected boolean shouldWait = false;
protected final List waitThreadQueue = new ArrayList();
/**
* For a thread to determine if it should wait. It it is, the thread will
* wait until notified.
*
*/
public void claimAccess() {
final Thread thread = getWaitThread();
if (thread != null) {
// let the thread wait untill notified
synchronized (thread) {
try {
thread.wait();
} catch (InterruptedException exp) {
}
}
}
}
/**
* For a thread to determine if it should wait. It it is, the thread will be
* put into the waitThreadQueue to wait.
*
*/
private synchronized Thread getWaitThread() {
Thread thread = null;
if (shouldWait || !waitThreadQueue.isEmpty()) {
thread = Thread.currentThread();
waitThreadQueue.add(thread);
}
shouldWait = true;
return thread;
}
/**
* Release the thread in the first position of the waitThreadQueue.
*
*/
public synchronized void releaseAccess() {
if (waitThreadQueue.isEmpty()) {
shouldWait = false;
} else {
shouldWait = true;
// give the claimAccess function a little time to complete
try {
Thread.sleep(10);
} catch (InterruptedException exp) {
}
// release the waiting thread
final Thread thread = (Thread) waitThreadQueue.remove(0);
synchronized (thread) {
thread.notifyAll();
}
}
}
}
Now my main method would be ..
public static void main (String args[])
{
}
please advise how I spawn thr threads in my my main method to test the above class..!!Please advise
This should get you started...
public static void main (String args[])
{
AccessGate gate = new AccessGate();
// create as many threads as you like
Thread t1 = new MyThread(gate);
Thread t2 = new MyThread(gate);
// start all the threads you created
t1.start();
t2.start();
}
class MyThread extends Thread {
AccessGate gate;
public MyThread(AccessGate g) {
gate = g;
}
public void run() {
gate.claimAccess();
// Do something or print something.
// Could output several statements.
// Why not do a sleep as well to see if other threads interrupt
// this code section.
gate.releaseAccess();
}
}
Consider using Executors.newSingleThreadExecutor(). This is a thread pool with only one thread executing tasks. Next task will start execution only after first task is finished:
Executor executor = Executors.newSingleThreadExecutor();
Future<String> future1 = executor.submit(new Callable<String>() {
#Override
String call() throws Exception {
// my first task
}
});
Future<String> future2 = executor.submit(new Callable<String>() {
#Override
String call() throws Exception {
// my second task
}
});
...
You can retrieve result of task execution via Future API, also it allows you to track status of each job.

run static method from a thread pool in java

What is the best way to run a static method in several threads, using a thread pool?
Also I trying to pass an argument to the static method. something like
Class A{
public static runTask(int i){
....
}
}
and from a main:
ThreadPool pool = new ThreadPool(5, "poolname");
for(int i=1; i<10; i++){
A.runTask(i) // but on a new thread...
}
Thanks!
Have a look at the documentation for java.util.concurrent.Executors. It should meet your needs. Here is a simple example of using it:
public class ExecutorServiceTest {
static ExecutorService threadPool = Executors.newCachedThreadPool();
public static void main(String[] args) throws Exception {
// Queue 10 executions of someTask into the threadPool
for(int i = 0; i < 10; i++) {
runSomeTaskInThreadPool();
}
// the shutdown method causes the executor to:
// 1. stop accepting new tasks, and
// 2. allow previously queued jobs to complete, and
// 3. shut down all pooled threads once all jobs are complete
threadPool.shutdown();
// block until the threadPool has finished shutting down,
// which indicates that all tasks have finished executing
threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
}
private static void runSomeTaskInThreadPool() {
Future future = threadPool.submit(new Runnable() {
public void run() {
someTask();
}
});
// TODO: Maybe keep track of futures to monitor success/failure of task
}
static AtomicInteger counter = new AtomicInteger();
public static void someTask() {
System.out.println("someTask: " + counter.incrementAndGet()
+ " on thread: " + Thread.currentThread());
}
}
Please find the detailed implementation guides:
http://java.sun.com/developer/Books/javaprogramming/threads/chap13.pdf

Categories

Resources