I am making a WordCounter, which has several threads counting the words in different files. I have gotten everything to work, except one little issue.
I cannot figure out a proper way to wait for the threads to finish. Everything works if I set a Thread.sleep to wait for a short amount of time, the only problem is that, this will not be a proper solution if the counter takes longer than the sleep does.
import java.io.*;
import java.util.*;
import java.util.concurrent.BlockingQueue;
public class WordCounter implements Runnable{
private String file;
private BlockingQueue<Integer> q;
private int words = 0;
public WordCounter(String f, BlockingQueue<Integer> queue){
file = f;
q = queue;
}
public void run(){
try{
Scanner in = new Scanner(new File(file));
while (in.hasNext()){
in.next();
words++;
}
in.close();
System.out.println(file + ": " + words);
q.add(words);
}
catch (FileNotFoundException e){
System.out.println(file + " blev ikke fundet.");
}
}
}
This is the code from the actual word-counter. I want my main-thread to wait for these word-counter threads to do the q.add(words); function before doing anything else.
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
public class MainThread implements Runnable{
private String[] arguments;
public MainThread(String[] args){
arguments = args;
}
public void run() {
final BlockingQueue<Integer> queue = new LinkedBlockingQueue<Integer>();
for(String f : arguments){
WordCounter c = new WordCounter(f, queue);
Thread t = new Thread(c);
t.start();
}
while(!queue.isEmpty()){
try {
System.out.println(queue.take());
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
This is the main-thread. I will need some sort of way to wait for the other threads to finish before I continue to my while statement at the bottom, but how?
Thanks in advance.
Use an ExecutorService and wait on the Future returned. The code below will submit each task to a thread within the executor service (thread pool) and get back the future for that task. When all submitted it will wait on the future. The get method will only return when the run method completes in the task.
public class MainThread implements Runnable{
private String[] arguments;
public MainThread(String[] args){
arguments = args;
}
public void run() {
ExecutorService e = Executors.newFixedThreadPool(arguments.length);
final BlockingQueue<Integer> queue = new LinkedBlockingQueue<Integer>();
List<Future<?>> tasks = new ArrayList<>();
for(String f : arguments){
tasks.add(e.submit(new WordCounter(f, queue)));
}
for(Future<?> f : tasks) {
f.get();
}
while(!queue.isEmpty()){
try {
System.out.println(queue.take());
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
However
You can make your code cleaner by removing the BlockingQueue entirely and having each task be a Callable<Integer> where it simply returns the words variable. And when you call future.get() the return value there would be the word count.
This is what i would do:
create a counter variable (here is how to do it in a way that is safe for multi-threads) to keep track of how many threads you are spawning in the main
thread
create an interface with function signatures to
increment/decrement that counter
implement that interface in your
main thread
subclass a worker thread to accept that interface as
a parameter
once the worker thread finishes, call that interface
to decrement the number of running threads.
in the implementation of the decrement function on the main thread, add a
condition to do something once the counter is 0.
If you know how many threads to wait on, then you can use a shared semaphore. The worker threads each calls release on the semaphore when they're done; the main thread calls acquire(n) where n is the number of worker threads, which causes the main thread to wait until n permits are available (i.e. until all n worker threads are finished).
You need to keep the created threads in a list and join them from the current thread.
Something like this:
List<Thread> threads = new LinkedList<Thread>();
for (String f : arguments) {
WordCounter c = new WordCounter(f, queue);
Thread t = new Thread(c);
t.start();
threads.add(t);
}
for (Thread t : threads) {
t.join();
}
The join() method will block until the thread terminates.
Related
class Callme{
synchronized void call(String msg){
System.out.print(msg);
try{
Thread.sleep(500);
System.out.println("message");
}catch(InterruptedException e){
System.out.println(e);
}
}
}
class Caller implements Runnable{
String message;
Thread t;
Callme target;
Caller(Callme target, String msg){
t = new Thread(this);
this.target = target;
message = msg;
t.start();
}
public void run(){
target.call(message);
}
}
class Synch{
public static void main(String args[]){
Callme c = new Callme();
Caller ob1 = new Caller(c,"1");
Caller ob2 = new Caller(c,"2");
Caller ob3 = new Caller(c,"3");
try{
ob1.t.join();
ob2.t.join();
ob3.t.join();
}catch(InterruptedException e){
System.out.println(e);
}
}
}
I am new to Java. I tried this sample program while learning about synchronization in threads. The first time I ran it, it gave me the expected output.
1message
2message
3message
But as I started running it repeatedly, the order changed. Like:
1message
3message
2message
Why does this happen? Shouldn't the threads enter call() in the specified order(i.e ob1,ob2,ob3)?
The reason you get output in random order is because the threads are running parallel and any of them could reach the synchronized block first, so they could print in any order.
If you want to get results in a defined order then you could use a Callable<String> instead of a Runnable and have it return the string you compute in the thread, then use the Futures of the tasks you submitted and get the results in your submission order. I added a timestamp to show that the later tasks sometimes still complete first, since they're all running parallel, but all the processing in CallMe.call(String) is still synchronized and thread safe-ish.
Using Callables and Futures lets you still get the benefits of parallelism and also gives you control when processing the results.
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
...
public static void main(String args[]) {
ExecutorService executor = Executors.newFixedThreadPool(3);
CallMe c = new CallMe();
List<Future<String>> futures = new ArrayList<>();
futures.add(executor.submit(new Caller(c, "1")));
futures.add(executor.submit(new Caller(c, "2")));
futures.add(executor.submit(new Caller(c, "3")));
try {
for (Future<String> future : futures) {
System.out.println(future.get());
}
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
executor.shutdown();
}
class Caller implements Callable<String> {
private String message;
private CallMe target;
Caller(CallMe target, String msg) {
this.target = target;
this.message = msg;
}
#Override public String call() {
return target.call(message);
}
}
class CallMe {
synchronized String call(String msg) {
try {
Thread.sleep(500);
return "message:" + msg + " - completed at system time " + new Timestamp(System.currentTimeMillis());
} catch (InterruptedException e) {
System.out.println(e);
return "error:" + e.getMessage();
}
}
}
For me it's:
3message
2message
1message
Why?
Because we started 3 threads that run concurrently.
Once we started the threads, the OS should give them CPU time. The first thread that arrives at the synchronized block will print to screen, the others will wait for it to finish, and so on.
If you want the printing to be pre-defined, then you should do:
Caller ob1 = new Caller(c,"1");
ob1.t.join();
Caller ob2 = new Caller(c,"2");
ob2.t.join();
Caller ob3 = new Caller(c,"3");
ob3.t.join();
But in most use-cases, you wouldn't do that, and instead don't use threads.
The synchronized keyword does not what you think it does. It simply protects the method, so only one thread can access it at a time. Therefore, the next number ("1", "2" or "3") can only be seen after "message" has been sent. The order of the threads, however, is not defined. Think about it like this: You basically call the methods at the same time (approximately). The JVM will spawn three threads that all begin execution immediately. One thread (always the first one) will call the method call and lock it so no other thread may access it. Now there are two threads waiting until call has finished so that they may use the method. The order in which they will call that method is completely arbitrary.
i'm wondering what the code would look like in order to have a program which creates a loop on start. This loop then creates several, thread objects all on their own threads so their all running at the same time, and they all run the same code. Is there a way to do this? as in for example we make 2 threads, they never stop looping and one is always prinintg "thread 1" and 1 is always printing "thread 2" at the same time. This is what i'm wondering. Thanks in advance!
class MyTask implements Runnable {
public static id = 0;
public MyTask(){
id++;
}
public void run(){
while(true){
System.out.print("Thread " + id);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Generator{
Public static void main(String[] args){
Runnable[] myTasks = new Runnable[2];
myTasks[0] = new MyTask();
myTasks[1] = new MyTask();
for(Runnable r: myTasks){
Thread t = new Thread(r);
t.start();
}
}
}
I didn't compile it. but this is how you are going to do.
When you run class Generator, two Threads will start, and they will print Thread 1. and thread 2 once every one second forever.
How can I make Callable thread as daemon thread?
Here is what I am trying. I am trying to execute a set of threads of which one of them does not complete and goes into infinite loop. What it does is the main thread of the program does not terminate even though all the code statements are executed. The main thread goes into suspended mode after that.
Here is the code snippet for the same.
public class MyThread implements Callable<String> {
private int value;
public MyThread(int value) {
this.value = value;
}
#Override
public String call() throws Exception {
//Thread.currentThread().setDaemon(true);
System.out.println("Executing - " + value);
if (value == 4) {
for (; ; );
}
return value + "";
}
}
Main Program
public class ExecutorMain {
public static String testing() {
ExecutorService executor = null;
List<Future<String>> result = null;
String parsedValue = null;
try {
executor = Executors.newSingleThreadExecutor();
List<MyThread> threads = new ArrayList<MyThread>();
for (int i = 1; i < 10; i++) {
MyThread obj = new MyThread(i);
threads.add(obj);
}
result = executor.invokeAll(threads, Long.valueOf("4000"), TimeUnit.MILLISECONDS);
//result = executor.invokeAll(threads);
for (Future<String> f : result) {
try {
parsedValue = f.get();
System.out.println("Return Value - " + parsedValue);
} catch (CancellationException e) {
System.out.println("Cancelled");
parsedValue = "";
f.cancel(true);
}
}
executor.shutdownNow();
} catch (Exception e) {
System.out.println("Exception while running threads");
e.printStackTrace();
} finally {
List executedThreads = executor.shutdownNow();
System.out.println(executedThreads);
for (Object o : executedThreads) {
System.out.println(o.getClass());
}
}
System.out.println("Exiting....");
//System.exit(1);
return "";
}
public static void main(String[] args) {
testing();
}
}
What I got to understand from my earlier question about Dangling threads in Java is that I have to make my threads as daemon threads.
How can I make Callable thread as daemon thread?
You need to use a new ThreadFactory that creates daemon threads. See this answer here: Executor and Daemon in Java
By default the executors create non-daemon threads whenever they build their pools. But you can inject your own ThreadFactory which creates the threads for the pool.
For example:
executor = ExecutorService.newSingleThreadExecutor(new MyThreadFactory());
The ThreadFactory implements the newThread method:
Thread newThread(Runnable r)
Copied from the answer I linked to above, you could implement it like:
class MyThreadFactory implements ThreadFactory {
public Thread newThread(Runnable r) {
Thread thread = new Thread(r);
thread.setDaemon(true);
return thread;
}
}
You mentioned in your question:
//Thread.currentThread().setDaemon(true);
Yeah, this won't work because you cannot set the daemon flag once the thread has been started.
It is not about making Callable to daemon. You actually want to make the execute threads become daemon. You can create the thread in this way to make it becomes daemon:
executor = Executors.newSingleThreadExecutor(new ThreadFactory(){
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setDaemon(true);
return t;
}
});
Just setting the Threads created by the ExecutorService to daemon won't help (though you do need to do this). You can set your ExecutorService Threads to daemon like so:
executor = Executors.newSingleThreadExecutor(new ThreadFactory() {
#Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setDaemon(true);
return t;
}
});
The real problem you are having is with this code block:
for (Future<String> f : result) {
try {
parsedValue = f.get();
System.out.println("Return Value - " + parsedValue);
} catch (CancellationException e) {
System.out.println("Cancelled");
parsedValue = "";
f.cancel(true);
}
}
executor.shutdownNow();
More specifically, this code will hang forever here:
parsedValue = f.get();
The reason for this is simple, the Future#get method "Waits if necessary for the computation to complete, and then retrieves its result.", but the computation will never complete because it is in an infinite loop. Not even an interrupt from ThreadPoolExecutor#shutdownNow or Future#cancel(true) will help you because your Callable code is not perofrming a blocking operation or otherwise checking for an interrupt.
From here, you have two options:
Use the form of Future#get that takes a long timeout argument.
Use Future#isDone to determine if the Future#get method has a value to return prior to actually calling Future#get.
Thanks Tim for the detailed explanation. However, your proposed solution did not solve the issue. The problem was that because the thread has gone to infinite loop, it does not check for any thread interruption and hence does not terminate.
For my scenario, infinite loop is not a good example, but what we were trying to accomplish is that we were executing a regular expression which was taking too long to execute and the check for interruption was after matcher.find() call. Because find() does not return in stipulated time and also the find() method does not check for thread interruptions, we were facing the dangling thread issue. Finally, implemented InterruptableCharSequence from this url and got it working.
Supposed I have a class MyThread, which implements Runnable with a method dosomething():
class MyThread implements Runnable{
Object dosomething(Parameter p){ ... }
run(){...};
}
If I do:
main(){
MyThread my = new MyThread().run();
Object o = my.dosomething(p);
}
will dosomething be executed on myThread or in the main Thread?
How can I start the execution of dosomething on myThread from the main Thread and retrieve the returned Object?
main(){
MyThread my = new MyThread().run();
Object o = my.dosomething(p);
}
If you do that it won't compile: you're trying to assign the result of a void method, void run(), to an object of type MyThread.
Implementing runnable and calling run() will not cause the code to be executed in a separate thread unless you pass it to another thread (i.e. Tread t = new Thread(my);)
How can I start the execution of dosomething on myThread from the main Thread and retrieve the returned Object?
You do that by storing the result of doSomething() in a location where you can access it later.
class MyClass
{
public Object doSomething()
{
// return the object
return new Object();
}
}
class MyRunnable implements Runnable
{
private final MyClass _mc;
private final object _lock;
private final List<object> _results;
public MyRunnable(MyClass mc, List<object> results, object lock)
{
_mc = mc;
_lock = lock;
_results = results;
}
public void run()
{
synchronized(_lock)
{
_results.add(_mc.doSomething());
}
}
}
So now in main:
void main(){
MyClass mc = new MyClass();
List<object> results = new List<object>();
object lock = new object();
// Execute your thread and wait for it to complete
Thread t = new Thread(new MyRunnable(mc, results, lock ));
t.start();
t.join();
// Get the results
for(object result:results)
{
// do something with the result
}
}
This should give you an idea of what you're doing "wrong." A more realistic example would be if you spawn multiple threads, run them concurrently and then join on all of them until they all complete.
Sounds like you may want to consider Callables and Futures.
There's a decent explanation at http://www.vogella.de/articles/JavaConcurrency/article.html#futures
You can use delegate, for example.
new MyThread(callWhenFinishObject)
It'll be executed on the main thread, since it's that thread that calls the method. If you want dosomething to run in the separate thread, have it called within run() and store the result in a myThread field for later retrieval.
You might want to check class Future or other stuff in java.util.concurrent for some convenient way of waiting for the result to become available.
EDIT: if dosomething should only run until some condition is satisfied that must be flagged in the main thread, have run() block until the main thread somehow signals the other thread that it's okay to go on.
EDIT 2: here, someone confirm this is what's being asked:
package threadtest;
public class Main {
public static void main(final String[] args) {
final MyThread otherThread = new MyThread();
System.out.println("Main thread: I'm gonna start the other thread now...");
otherThread.start();
System.out.println("Main thread: there, hope it does well.");
try {
Thread.sleep(1000); //Lets main thread take a snooze...
} catch(InterruptedException ex) {
//whatever
}
System.out.println("Main thread: I'm gonna do some stuff in the meantime...");
try {
Thread.sleep(200); //Lets main thread take a snooze...
} catch(InterruptedException ex) {
//whatever
}
System.out.println("Main thread: maybe clean up the kitchen.");
try {
Thread.sleep(1000); //Lets main thread take a snooze...
} catch(InterruptedException ex) {
//whatever
}
System.out.println("Main thread: does other thread have something for me yet?");
if(otherThread.getResult() == null)
System.out.println("Main thread: nope, not yet.");
try {
Thread.sleep(500); //Lets main thread take a snooze...
} catch(InterruptedException ex) {
//whatever
}
System.out.println("Main thread: oh crap! I forgot to tell it that it may execute its method!");
otherThread.allowToExecute();
System.out.println("Main thread: phew... better keep checking now before it gets angry.");
while(otherThread.getResult() == null) {
try {
Thread.sleep(100); //Lets main thread take a snooze...
} catch(InterruptedException ex) {
//whatever
}
}
System.out.println("Main thread: there we go, it gave me a result. Rest in peace, other thread...");
}
private static class MyThread extends Thread {
private boolean mayExecuteDoSomething = false;
private Object result = null;
#Override
public void run() {
System.out.println("Other thread: whoa, someone started me!");
while(!mayExecuteDoSomething) {
try {
Thread.sleep(100); //I'm gonna sleep for a bit...
} catch(InterruptedException ex) {
//whatever
}
}
System.out.println("Other thread: alright, I'm allowed to execute my method!");
result = doSomething();
System.out.println("Other thread: there, did it. I'll just call it quits now.");
}
public void allowToExecute() {
mayExecuteDoSomething = true;
}
private Object doSomething() {
return new Object();
}
public Object getResult() {
return result;
}
}
}
This is a very crude approach to the issue. The basic concepts are there, though. In reality, you'd want to use stuff like Callable and Future for proper asynchronous computation.
That is not possible.
When you create a thread, it runs the code in run() and exits.
There is no way to inject code into a different thread; that would break the core execution model. (Within a thread, your code runs sequentially, with nothing in between)
If you want to, you can create a thread that listens for callback (Runnable instances) in a queue and executes them (like a message loop).
This is how the UI thread works.
Also, you aren't actually startign a thread; you need to write new Thread(someRunnable).start()
I am doing a college assignment(to be frank enough). The problem is that I should have 4 client threads running at any time (uptil a number n). So, whenver any thread terminates, a new thread must be spawned.
public static void main(String[] args) throws IOException,InterruptedException
{
/* some declarations.. */
ClientThread client=new ClientThread ();
Runnable intr =client;
for(count=1;count<=number;count++)
{
/* If 4 client threads has been spawned, wait until 1 of them exits */
while(Thread.activeCount()<5)
;
new Thread(intr).start();
}
/* Wait until all other threads exits. */
while(Thread.activeCount()!=1)
;
System.out.println("\n The sum of factorials is: "+client.getResult());
}
I want to remove the busy-waiting as it defeats the very purpose of my program. How can i make the main thread wait ?? (It shows wait is a nonstatic method and cannot be invoked from a static method.) Please help.
java.util.concurrent.CountDownLatch is designed for your case.
Define CountDownLatch doneSignal = new CountDownLatch(4);
doneSignal.await() will wait until doneSignal.countDown() is called four times.
So let ClientThreads hold sames reference doneSignal, when run() exits, call doneSignal.countDown().
class ClientThread implements Runnable {
private final CountDownLatch doneSignal;
ClientThread (CountDownLatch doneSignal) {
this.doneSignal = doneSignal;
}
public void run() {
try {
//Do something
doneSignal.countDown();
} catch (InterruptedException ex) {}
}
}
...
//In main thread
doneSignal.await();
Hmm - do you have to do it by hand or does your teacher expect that you discover Executors.newFixedThreadPool(4)?
That's exactly what a thread pool with four worker threads would do: no more then four clients run in parallel, if one terminates, the free'd worker thread is ready to "get a new job".
It's pretty simple:
public void test(int threads, int runnables) {
ExecutorsService pool = Executors.newFixedThreadPool(threads);
Runnable r = new Runnable() {
public void run() {
// calculate a factorial or do something else
System.out.println(Thread.currenThread());
}
}
for (int i = 0; i < runnables; i++)
pool.execute(r);
}
Let runnables be bigger then threads and you'll see from the result that at most threads number of threads are (re-)used to execute the runnables.
You can write a callback method in your main class, that is called by an exiting thread and spawns a new one. By using a static field in the main class you will keep track of the number of threads spawned to obtain the same effect as the current code.
it would look somehow like this :
class Main{
private static ClientThread client;
private static Runnable intr;
private static int count;
public static void main(String[] args)
{
count = 10; //Or something else
runningThreads = 0;
client=new ClientThread ();
intr =client;
for(i=0;i<5;i++)
spawnThread();
}
private static void spawnThread()
{
Thread newThread;
if(count>0)
{
newThread = new Thread(intr);
newThread.start();
count--;
}
if(count==0)
System.out.println("\n The sum of factorials is: "+client.getResult());
}
Take a look # classes in java.util.concurrent
Specifically
java.util.concurrent.CountDownLatch
java.util.concurrent.locks.Condition
For the main thread you can use:
Thread.getCurrent().join();
This will wait for all the spawned threads to die, before the main thread terminates.