I have a worker threadpool set up that executes a bit of work which I want to log in a central place.
To be more precise, I've extended the Thread class into a worker class, which checks the status of a concurrent queue. If it's empty, then it waits. As elements are added by another thread, notify() wakes the workers. Once they've completed the task, they wait for the next element in the queue.
What's the best practice to have each of the threads report their status at the end of each of their tasks?
public class PoolWorker extends Thread {
public ConcurrentLinkedQueue<Device> q;
public PoolWorker(ConcurrentLinkedQueue<Device> q, String type){
this.q = q;
this.type = type;
}
#Override
public void run(){
while (true)
{
Device d = null;
try{
synchronized(q){
while(q.isEmpty())
{
q.wait(); // wait for a notify()
}
d = q.remove();
}
// do some work
// report status of work completed
}
}
Try to do something like this
ExecutorService exec = Executors.newFixedThreadPool(10);
Runnable runn = new Runnable()
{
#Override
public void run()
{
System.out.println("");
}
};
exec.execute(runn);
As mentioned best way is to use BlockingQueue. Below is the sample code:
public class PoolWorker extends Thread {
public ArrayBlockingQueue<String> q;
public String type;
public PoolWorker(ArrayBlockingQueue<String> q, String type) {
this.q = q;
this.type = type;
}
#Override
public void run() {
while(true){
String work = null;
try {
System.out.println("PoolWorker.run:waiting .............");
work = q.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("PoolWorker.run..work: " + work);
}
}
public static void main(String[] args) throws InterruptedException {
ArrayBlockingQueue<String> pool = new ArrayBlockingQueue<String>(100);
PoolWorker worker = new PoolWorker(pool, "Something");
worker.start();
addWork(pool, "work1");
addWork(pool, "work2");
addWork(pool, "work3");
addWork(pool, "work4");
addWork(pool, "work5");
//Just give enough time to run
Thread.sleep(5000);
}
private static void addWork(ArrayBlockingQueue<String> pool, String work) throws InterruptedException {
System.out.println("PoolWorker.addWork: " + work);
pool.put(work);
}
}
There is nice sample code available in Java documentation as well:
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/BlockingQueue.html
Related
I'm currently working on java application which has a scenario of multiple producers adding tasks to a queue and whenever queue is not empty tasks should be executed at predefined rate. (using multiple threads to maintain execution rate) After executing the available tasks executor has to wait till tasks available in the queue again.
I know blockingQueue can be used to triggering part in here and ScheduledExecutorService for execute tasks at fixed rate. But I could not find a way to link ability of both of this for my need. So I would be very thankful if you could give me any suggestion to make this happen.
You need the task queue to be accessible by both the producer and consumer threads. I've written a basic program to demonstrate this, but I'll let you play around with the BlockingQueue API and the ScheduledExecutor as per your needs:
import java.util.concurrent.*;
public class ProducerConsumer {
private static final BlockingQueue<Integer> taskQueue = new LinkedBlockingQueue<>();
public static void main(String[] args) {
ExecutorService consumers = Executors.newFixedThreadPool(3);
consumers.submit(new Consumer());
consumers.submit(new Consumer());
consumers.submit(new Consumer());
ExecutorService producers = Executors.newFixedThreadPool(2);
producers.submit(new Producer(1));
producers.submit(new Producer(2));
}
private static class Producer implements Runnable {
private final int task;
Producer(int task) {
this.task = task;
}
#Override
public void run() {
System.out.println("Adding task: " + task);
taskQueue.add(task); // put is better, since it will block if queue is full
}
}
private static class Consumer implements Runnable {
#Override
public void run() {
try {
Integer task = taskQueue.take(); // block if there is no task available
System.out.println("Executing task: " + task);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
This is the way I could come up with as a solution. It looks little bit rusty but I have tested this and the code is working.
package test;
import java.util.concurrent.*;
public class FixedRateConsumer {
private BlockingQueue<String> queue = new ArrayBlockingQueue<>(20);
private ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(5);
private boolean continueRunning = true;
public void executeInBackGraound() throws InterruptedException, ExecutionException {
while (continueRunning) {
String s = queue.take();
Worker w = new Worker(s);
ScheduledFuture future = executorService.scheduleAtFixedRate(w, 0, 1, TimeUnit.SECONDS);
w.future = future;
try {
if (!future.isDone()) {
future.get();
}
} catch (CancellationException e) {
// Skipping
}
}
}
public void setContinueRunning(boolean state) {
continueRunning = state;
}
public void addConsumableObject(String s) throws InterruptedException {
queue.put(s);
}
private void consumeString(String s) {
System.out.println("Consumed -> " + s + ", ... # -> " + System.currentTimeMillis() + " ms");
}
private class Worker implements Runnable {
String consumableObject;
ScheduledFuture future;
public Worker(String initialConsumableObject) {
this.consumableObject = initialConsumableObject;
}
#Override
public void run() {
try {
if (consumableObject == null) {
consumableObject = queue.take();
}
consumeString(consumableObject);
consumableObject = null;
if (queue.isEmpty()) {
if (future == null) {
while (future == null) {
Thread.sleep(50);
}
}
future.cancel(false);
}
} catch (Exception e) {
System.out.println("Exception : " + e);
}
}
}
}
I have a problem with some threads.
My script
1 - loads like over 10 millions lines into an Array from a text file
2 - creates an ExecutorPool of 5 fixed threads
3 - then it is iterating that list and add some threads to the queue
executor.submit(new MyCustomThread(line,threadTimeout,"[THREAD "+Integer.toString(increment)+"]"));
Now the active threads never bypass 5 fixed threads, which is good, but i obseved that my processor goes into 100% load, and i have debuged a little bit and i saw that MyCustomThread constructor is being called, witch means that no matter if i declare 5 fixed threads, the ExecutorService will still try to create 10 milions objects.
The main question is :
How do i prevent this? I just want to have threads being rejected if they don't have room, not to create 10 million object and run them one by one.
Second question :
How do i get the current active threads? I tried threadGroup.activeCount() but it always give me 5 5 5 5 ....
THE CALLER CLASS :
System.out.println("Starting threads ...");
final ThreadGroup threadGroup = new ThreadGroup("workers");
//ExecutorService executor = Executors.newFixedThreadPool(howManyThreads);
ExecutorService executor = Executors.newFixedThreadPool(5,new ThreadFactory() {
public Thread newThread(Runnable r) {
return new Thread(threadGroup, r);
}
});
int increment = 0;
for(String line : arrayOfLines)
{
if(increment > 10000)
{
//System.out.println("TOO MANY!!");
//System.exit(0);
}
System.out.println(line);
System.out.println(threadGroup.activeCount());
if(threadGroup.activeCount() >= 5)
{
for(int i = 0; i < 10; i++)
{
System.out.println(threadGroup.activeCount());
System.out.println(threadGroup.activeGroupCount());
Thread.sleep(1000);
}
}
try
{
executor.submit(new MyCustomThread(line,threadTimeout,"[THREAD "+Integer.toString(increment)+"]"));
}
catch(Exception ex)
{
continue;
//System.exit(0);
}
increment++;
}
executor.awaitTermination(10, TimeUnit.MILLISECONDS);
executor.shutdown();
THREAD CLASS :
public class MyCustomThread extends Thread
{
private String ip;
private String threadName;
private int threadTimeout = 10;
public MyCustomThread(String ip)
{
this.ip = ip;
}
public MyCustomThread(String ip,int threadTimeout,String threadName)
{
this.ip = ip;
this.threadTimeout = threadTimeout;
this.threadName = threadName;
System.out.prinln("MyCustomThread constructor has been called!");
}
#Override
public void run()
{
// do some stuff that takes time ....
}
}
Thank you.
You are doing it a bit wrong. The philosophy with executors is that you implement the work unit as a Runnable or a Callable (instead of a Thread). Each Runnable or Callable should do one atomic piece of work which is mutually exclusive of other Runnables or Callables.
Executor services internally use a pool of threads so your creating a thread group and Thread is not doing any good.
Try this simple piece:
ExecutorService executor = Executors.newFixedThreadPool(5);`
executor.execute(new MyRunnableWorker());
public class MyRunnableWorker implements Runnable{
private String ip;
private String threadName;
private int threadTimeout = 10;
public MyRunnableWorker(String ip){
this.ip = ip;
}
public MyRunnableWorker(String ip,int threadTimeout,String threadName){
this.ip = ip;
this.threadTimeout = threadTimeout;
this.threadName = threadName;
System.out.prinln("MyRunnableWorker constructor has been called!");
}
#Override
public void run(){ {
// do some stuff that takes time ....
}
}
This would give you what you want. Also try to test you thread code execution using visualVM to see how threads are running and what the load distribution.
I think your biggest problem here is that MyCustomThread should implement Runnable, not extend Thread. When you use an ExecutorService you let it handle the Thread management (i.e. you don't need to create them.)
Here's an approximation of what I think you're trying to do. Hope this helps.
public class FileProcessor
{
public static void main(String[] args)
{
List<String> lines = readFile();
System.out.println("Starting threads ...");
ExecutorService executor = Executors.newFixedThreadPool(5);
for(String line : lines)
{
try
{
executor.submit(new MyCustomThread(line));
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
try
{
executor.shutdown();
executor.awaitTermination(10, TimeUnit.SECONDS);
}
catch (InterruptedException e)
{
System.out.println("A processor took longer than the await time to complete.");
}
executor.shutdownNow();
}
protected static List<String> readFile()
{
List<String> lines = new ArrayList<String>();
try
{
String filename = "/temp/data.dat";
FileReader fileReader = new FileReader(filename );
BufferedReader bufferedReader = new BufferedReader(fileReader);
String line = null;
while ((line = bufferedReader.readLine()) != null) {
lines.add(line);
}
bufferedReader.close();
}
catch (Exception e)
{
e.printStackTrace();
}
return lines;
}
}
public class MyCustomThread implements Runnable
{
String line;
MyCustomThread(String line)
{
this.line = line;
}
#Override
public void run()
{
System.out.println(Thread.currentThread().getName() + " processed line:" + line);
}
}
EDIT:
This implementation does NOT block on the ExecutorService submit. What I mean by this is that a new instance of MyCustomThread is created for every line in the file regardless of whether any previously submitted MyCustomThreads have completed. You could add a blocking / limiting worker queue to prevent this.
ExecutorService executor = new ThreadPoolExecutor(5, 5, 0L, TimeUnit.MILLISECONDS, new LimitedQueue<Runnable>(10));
An example of a blocking / limiting queue implementation can be found here:
I have started threads in sequence but i don't know how to stop them in reverse sequence.
For example:
they are starting like this: A->B->C->D
and I want them to stop: D->C->B->A
I don't know how to stop threads at all and not even in this order.
I appreciate any help or advice.
import java.util.*;
class Service extends Thread
{
private RobotController controller;
private String robotID;
private byte[] lock;
public Service(RobotController cntrl, String id)
{
controller = cntrl;
robotID = id;
}
public byte[] getLock() { return lock;}
public void run()
{
lock = new byte[0];
synchronized(lock)
{
byte[] data;
while ((data = controller.getData()) == null)
{
try {
lock.wait();
} catch (InterruptedException ie) {}
}
System.out.println("Robot " + robotID + " Working");
}
}
}
class RobotController
{
private byte[] robotData;
private Vector threadList = new Vector();
private Service thread_A;
private Service thread_B;
private Service thread_C;
private Service thread_D;
private volatile boolean done;
public void setup(){
thread_A = new Service(this, "A");
thread_B = new Service(this, "B");
thread_C = new Service(this, "C");
thread_D = new Service(this, "D");
threadList.addElement(thread_A);
threadList.addElement(thread_B);
threadList.addElement(thread_C);
threadList.addElement(thread_D);
thread_A.start();
thread_B.start();
thread_C.start();
thread_D.start();
start();
stop();
}
public void start()
{
System.out.println("Thread starts");
{
for (int i=0; i <= 3; i++)
{
try {
Thread.sleep(500);
}catch (InterruptedException ie){}
putData(new byte[10]);
Service rbot = (Service)threadList.elementAt(i);
byte[] robotLock = rbot.getLock();
synchronized(robotLock) {
robotLock.notify();
}
}
}
}
public void stop()
{
{
}
}
public synchronized byte[] getData()
{
if (robotData != null)
{
byte[] d = new byte[robotData.length];
System.arraycopy(robotData, 0, d, 0, robotData.length);
robotData = null;
return d;
}
return null;
}
public void putData(byte[] d) { robotData = d;}
public static void main(String args[])
{
RobotController controller = new RobotController();
controller.setup();
}
}
I'll usually include something like a cancel() method in my threads if I want to explicitly terminate them.
class Service extends Thread {
private volatile boolean cancel = false;
public void cancel() {
cancel = true;
}
public void run() {
...
while (!cancel && (data = controller.getData()) == null) {
...
}
}
}
Keep your threads in a stack as mre suggests, then pop through the stack and call cancel and then interrupt on each thread.
I have started threads in sequence but i don't know how to stop them in reverse sequence.
This is difficult to do. There are ways you can stop a thread either by setting a volatile shutdown boolean or interrupting them, but none of these mechanisms are guaranteed to stop a thread immediately.
You certainly can keep a List<Thread> when you build them, call Collections.reverse(threadList) and then call thread.interrupt() on each one in turn. If you must have them finish in order then you should interrupt() them and then join them. Something like:
Collections.reverse(threadList);
for (Thread thread : threadList) {
thread.interrupt();
thread.join();
}
Then each thread should be doing something like:
while (!Thread.currentThread().isInterrupted()) {
...
}
Note that if you are running Thread.sleep(...) or other methods that throw InterruptedException, you'll need to re-enable the interrupt flag:
try {
Thread.sleep(...);
} catch (InterruptedException e) {
// by convention if InterruptedException thrown, interrupt flag is cleared
Thread.currentThread().interrupt();
...
}
Have each thread keep a reference to the next thread to be started. Then each thread can periodically check to see if the thread is still alive. If not, that thread should terminate. When it does, the previous thread will notice and terminate, and so on up the chain.
abstract class ChainThread extends Thread {
private final Thread next;
ChainThread(Thread next) { this.next = next; }
#Override
public final void run() {
next.start();
while (!Thread.currentThread().isInterrupted() && next.isAlive()) {
do();
}
}
abstract void do();
}
If I read the Service code correctly, it waits until there's data to execute on, then finishes. So you don't really need an explicit stop or cancel type signal, the threads will terminate themselves after they do work.
To enforce ordering of shutdown, you could make each Service aware of the previous Service, and then call previousService.join(). Assuming no InterruptedExceptions are thrown, they will then shutdown in order after seeing that the controller has data.
Create the Services this way:
Service serviceA = new Service(controller, "A", null);
Service serviceB = new Service(controller, "B", serviceA);
Service serviceC = new Service(controller, "C", serviceB);
Service serviceD = new Service(controller, "D", serviceC);
and the implementation is edited to exit only after dependent Services are complete:
private final RobotController controller;
private final String robotID;
private byte[] lock;
private final Service dependentService;
public Service(RobotController cntrl, String id, Service dependentService) {
controller = cntrl;
robotID = id;
this.dependentService = dependentService;
}
public byte[] getLock() {
return lock;
}
#Override
public void run() {
lock = new byte[0];
synchronized (lock) {
byte[] data;
while ((data = controller.getData()) == null) {
try {
lock.wait();
}
catch (InterruptedException ie) {
}
}
System.out.println("Robot " + robotID + " Working");
}
if (dependentService != null) {
try {
dependentService.join();
}
catch (InterruptedException e) {
this.interrupt();
}
}
}
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 9 years ago.
I want to concurrently execute two methods, named A and B.
I also want B to wait for A to finish.
How can I achieve such results by implementing threads in Java?
Use Thread#join(). Call it on thread object which death you want to wait for.
The join method allows one thread to wait for the completion of another.
Example from official tutorial:
public class SimpleThreads {
// Display a message, preceded by
// the name of the current thread
static void threadMessage(String message) {
String threadName =
Thread.currentThread().getName();
System.out.format("%s: %s%n",
threadName,
message);
}
private static class MessageLoop
implements Runnable {
public void run() {
String importantInfo[] = {
"Mares eat oats",
"Does eat oats",
"Little lambs eat ivy",
"A kid will eat ivy too"
};
try {
for (int i = 0;
i < importantInfo.length;
i++) {
// Pause for 4 seconds
Thread.sleep(4000);
// Print a message
threadMessage(importantInfo[i]);
}
} catch (InterruptedException e) {
threadMessage("I wasn't done!");
}
}
}
public static void main(String args[])
throws InterruptedException {
// Delay, in milliseconds before
// we interrupt MessageLoop
// thread (default one hour).
long patience = 1000 * 60 * 60;
// If command line argument
// present, gives patience
// in seconds.
if (args.length > 0) {
try {
patience = Long.parseLong(args[0]) * 1000;
} catch (NumberFormatException e) {
System.err.println("Argument must be an integer.");
System.exit(1);
}
}
threadMessage("Starting MessageLoop thread");
long startTime = System.currentTimeMillis();
Thread t = new Thread(new MessageLoop());
t.start();
threadMessage("Waiting for MessageLoop thread to finish");
// loop until MessageLoop
// thread exits
while (t.isAlive()) {
threadMessage("Still waiting...");
// Wait maximum of 1 second
// for MessageLoop thread
// to finish.
t.join(1000);
if (((System.currentTimeMillis() - startTime) > patience)
&& t.isAlive()) {
threadMessage("Tired of waiting!");
t.interrupt();
// Shouldn't be long now
// -- wait indefinitely
t.join();
}
}
threadMessage("Finally!");
}
}
What you need is the Future class of Java. It make very simple to access the results of a method that is called asynchronously.
Check the Javadocs http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/Future.html for a better explanation.
Cheers
I'm not sure what you mean by "I want B to wait for A to finish", I took it to mean B needs to run after A.
You can do this easily using the ExecutorService, in this example it is a singleThreadExecutorService so it is guaranteed to run B after A.
The only issue is that if A exits with a problem it will not be picked up so you may want to assign a watchdog thread to pick up the status of A using the Future.get method and then schedule B if A is successful.
public static Object a() {
return new Object();
}
public static Object b() {
return new Object();
}
public static class CallA implements Callable<Object> {
public Object call() throws Exception {
return a();
}
}
public static class CallB implements Callable<Object> {
public Object call() throws Exception {
return b();
}
}
public static void main(String[] args) {
final ExecutorService executorService = Executors.newSingleThreadExecutor();
final Future<Object> aFuture = executorService.submit(new CallA());
final Future<Object> bFuture = executorService.submit(new CallB());
try {
aFuture.get();
bFuture.get();
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
} catch (ExecutionException ex) {
throw new RuntimeException(ex);
}
}
I would recommend that you do not mess about the Threads unless you know what you're doing - it can lead down a dangerous road. Use the Executors provided and you are much less likely to run into concurrency issues.
Here's a sample Two-Threads code fragment you should be able to start with:
public class TwoThreads {
public static void main(String args[]) throws InterruptedException {
System.out.println("TwoThreads:Test");
new TwoThreads().test();
}
// The end of the list.
private static final Integer End = -1;
static class Producer implements Runnable {
final Queue<Integer> queue;
public Producer(Queue<Integer> queue) {
this.queue = queue;
}
#Override
public void run() {
try {
for (int i = 0; i < 1000; i++) {
queue.add(i);
Thread.sleep(1);
}
// Finish the queue.
queue.add(End);
} catch (InterruptedException ex) {
// Just exit.
}
}
}
static class Consumer implements Runnable {
final Queue<Integer> queue;
public Consumer(Queue<Integer> queue) {
this.queue = queue;
}
#Override
public void run() {
boolean ended = false;
while (!ended) {
Integer i = queue.poll();
if (i != null) {
ended = i == End;
System.out.println(i);
}
}
}
}
public void test() throws InterruptedException {
Queue queue = new LinkedBlockingQueue();
Thread pt = new Thread(new Producer(queue));
Thread ct = new Thread(new Consumer(queue));
// Start it all going.
pt.start();
ct.start();
// Wait for it to finish.
pt.join();
ct.join();
}
}
use wait and notify methods on a common object
Class ClassA implements runnable{
Message messageA;
public ClassA(Message messageA){
this.messageA = messageA;
}
public void run(){
//code here
messageA.notify();
}
}
Class ClassB implements runnable{
Message messageA;
public ClassB(Message messageA){
this.messageA = messageA;
}
public void run(){
messageA.wait();
//code here
}
}
public static void main(){
Message message = new Message();// a simplest object here can be String
//ctreate thread of ClassA(message);
//create thread of classB(message);
}
the threadB will wait untill thread A sends a notify on message object.
Use Thread#join() from oracle javadocs here
I have a class that iterates through a list of links. For each link I want to do a treatment. So I have to create a thread for each link.
Here is the code (Main):
ThreadProcessing tp;
for(int i = 0; i < listUrl.size(); i++)
{
tp.add(string_url);
}
For the ThreadProcessing class, I have to use the Executor interface.
The point is : I have to create a pool of 30 threads. ThreadP class contains a list of non-blocking threads (it can contain more than 30 threads of course). You can add as many threads as you want and the class will be responsible to perform all these threads.
So that's what I tried to do (it does not work).The ThreadProcessing class :
public class ThreadProcessing {
List<Runnable> runnables = new ArrayList<Runnable>();
ExecutorService pool;
#PostConstruct
public void init()
{
pool = Executors.newFixedThreadPool(30);
}
public void add(String url)
{
runnables.add(createRunnable(url));
executeRunnables(pool, runnables);
}
public static void executeRunnables(final ExecutorService service, List<Runnable> runnables){
for(Runnable r : runnables){
service.execute(r);
}
service.shutdown();
}
private Runnable createRunnable(final String url){
Runnable getContentFromURL = new Runnable(){
public void run(){
//My treatment with url
}
};
return getContentFromURL;
}
}
I hope I have not been too vague in my explanation, thank you.
public void add( String url) {
Runnable job = createRunnable(url);
runnables.add( job);
pool.execute( job);
}
Also, do not shut the pool down unless you are finished submitting/adding jobs. Of course, in this example, you don't really need the runnables List.
Try something like:
public void main() {
ExecutorService es = Executors.newFixedThreadPool(30);
BlockingQueue<String> urls =
new ArrayBlockingQueue<String>(listUrl.size(), false, listUrl);
LinkedList<Future<?>> futures = new LinkedList<Future<?>>();
for(int i = 0 ; i < 30 ; ++i) {
futures.add(es.submit(new URLRunnable(urls)));
}
// Wait for all the futures to return
for(Future<?> f : futures) {
f.get();
}
}
public class URLRunnable() implements Runnable() {
private final BlockingQueue<String> urls;
URLRunnable(BlockingQueue<String> urls) { this.urls = urls; }
#Override
public void run() {
String url = null;
while((url = urls.poll()) != null) {
// do something with url
}
}
}