I am running a very simple multi thread program
Main program
package javathread;
public class JavaThread {
public static void main(String[] args)
{
JThread t1 = new JThread(10,1);
JThread t2 = new JThread(10,2);
t1.run();
t2.run();
}
}
JThread.java
package javathread;
import java.util.Random;
public class JThread implements Runnable
{
JThread(int limit , int threadno)
{
t = new Thread();
this.limit = limit;
this.threadno = threadno;
}
public void run()
{
Random generator = new Random();
for (int i=0;i<this.limit;i++)
{
int num = generator.nextInt();
System.out.println("Thread " + threadno + " : The num is " + num );
try
{
Thread.sleep(100);
}
catch (InterruptedException ie)
{
}
}
}
Thread t;
private int limit;
int threadno;
}
I expect both threads to run concurrently/parrallel , something similar to this picture
Instead I am getting this where thread 1 runs first then thread 2 runs
Can someone explain to me why this is happening ??
How do i get the threads to run concurrently ??
Because you called t1.run() and t2.run() instead of t1.start() and t2.start().
If you call run, it's just a normal method call. It doesn't return until it's finished, just like any method. It does not run anything concurrently. There is absolutely nothing special about run.
start is the "magic" method that you call to start another thread and call run in the new thread. (Calling start is also a normal method call, by the way. It's the code inside start that does the magic)
Please go through the Life Cycle of a Thread.
you don't run anything on the Thread, you just run the Runnable (your JThread is NOT a thread, it is just a unnable).
to run on a thread, you need to do something like this:
new Thread(myRunnable).start();
creating the thread in the Runnable does nothing (like you did in JThread constructor).
Because you should start() the Thread, not run() it.
Related
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.
I have a 2 threads defined in an android activity. Both threads are created as runnable instances. Thread 1 is a runnable object called "timer1" (created using an anonymous inner class) and Thread 2(assigned to runnable object "timer2") is invoked from Thread 1 using Thread 2's handler (using the post() method).
Thread 2's handler is called "tempHandler" (it is an instance variable) and is initialized in the constructor of the "MyRunnable" class.
Thread1 makes 5 calls to Thread2 in a for loop. The intended outcome is that Thread2 should run each time a post() call is made to it. But it does not happen. Instead the entire loop in Thread1 completes and only then does Thread2 run. Why does this happen? And how to rectify it?
This is the 1st thread:
timer1 = new Runnable() {
#Override
public void run() {
timer2 = new MyRunnable();
for(int i = 0; i < 5; i++){
tempHandler.post(timer2);
try{
Thread.sleep(1000);
} catch(Exception e) {
System.out.println(e.getMessage());
}
}
}
};
This is the 2nd thread:
public class MyRunnable implements Runnable {
public MyRunnable() {
tempHandler = new Handler();
}
#Override
public void run() {
if(Looper.myLooper() == null) {
Looper.prepare();
}
long startTime = System.currentTimeMillis();
long stopTime = System.currentTimeMillis();
long elapsedTime = stopTime - startTime;
System.out.println("Array traversal time: " + String.valueOf(elapsedTime));
System.out.println("Exited thread 2");
Looper.loop();
}
}
You haven't shown the code that starts the threads, but it sounds like maybe you're assuming Runnables are Threads. They're not.
A Runnable is just that: a thing you can run by calling its run() method. But it runs in the same thread you call it from.
An example to see what I'm talking about:
public static void main(String[] args) {
final Thread mainThread = Thread.currentThread();
Runnable r = new Runnable() {
#Override
public void run() {
System.out.println(mainThread);
System.out.println(Thread.currentThread());
System.out.println(mainThread == Thread.currentThread());
}
};
r.run();
}
The output is something like:
Thread[main,5,main]
Thread[main,5,main]
true
You create a separate thread which will run the Runnable by calling new Thread(r). Replacing the line r.run(); in the above example with:
Thread newThread = new Thread(r);
newThread.start();
The output becomes:
Thread[main,5,]
Thread[Thread-0,5,main]
false
Success – we have two different threads!
Note: make certain you are calling start() on your Thread objects, and not run(). That's the other possible reason your code isn't working. Although Thread objects have a public run() method, this is a historical mistake in Java; you should never call it, because that just runs the code on the current thread without starting a new one.
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.
This is good example of stopping thread.
How to stop a java thread gracefully?
But when I try to check this example I received infinite loop.
This is my code:
public class Num {
public void crash(ManualStopping t1) {
t1.stopMe();
}
public static void main(String[] args) {
Num num = new Num();
ManualStopping t1 = new ManualStopping();
t1.run();
System.out.println("Main thread");
num.crash(t1);
}
}
class ManualStopping extends Thread {
volatile boolean finished = false;
public void stopMe() {
finished = true;
}
public void run() {
while (!finished) {
System.out.println("I'm alive");
}
}
}
I think you need to start your thread - not run it. By calling run, you are just making a normal method call, not running a separate thread.
Nothing in your code calls the stopMe method on ManualStopping. isInterrupted() is a test that doesn't change the state of the thread. And as #DaveHowes points out, you don't even start a separate thread.
t1.run(); Change it to t1.start().
Whats happening is that the thread you intend to spawn is not actually running as a separate thread. Instead the loop
while(!finished){ System.out.println("I'm alive"); }
is running on the main thread and your code num.crash(t1); never actually gets invoked. This is causing the infinite loop.
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.