Threads are stored in an ArrayList so that they can dynamically be set later on by their name. There are a lot of examples on the Internet, all about this, but I do not work, so the selected thread does not stop.
What can my fault be?
public class Szal {
static ArrayList<MyThread> myThread;
static String[] names;
public Szal() {
myThread = new ArrayList<MyThread>();
names = new String[]{"EZ", "AZ"};
for (int i = 0; i < names.length; i++) {
MyThread t = new MyThread(names[i]);
myThread.add(t);
t.start();
}
}
public static void main(String[] args) {
new Szal();
Thread[] thread = new Thread [Thread.activeCount ()];
int m = Thread.enumerate (thread);
for (int i = 0; i < m; i++) {
System.out.println (thread[i].getName());
}
// Why is this not working?
for (Thread t : myThread) {
if (t.getName().equalsIgnoreCase("EZ")) {
t = Thread.currentThread();
t.interrupt();
myThread.remove(t);
}
}
Thread[] threads = new Thread [Thread.activeCount ()];
int c = Thread.enumerate (threads);
for (int i = 0; i < c; i++) {
System.out.println (threads[i].getName());
}
}
class MyThread extends Thread {
public MyThread(String name) {
super(name);
}
public void run() {
while (true) {
}
}
}
}
//this why not working???
for(Thread t : myThread){
if(t.getName().equalsIgnoreCase("EZ")){
t= Thread.currentThread();
t.interrupt();
myThread.remove(t);
}
}
You iterate over all threads in the list and iterrupt yourself as soon as you reach the one with the name EZ. I'm not sure if that's what you actually planned to do, your question sounded more like you wanted to interrupt the EZ-Thread. In that case you should omit the line t = Thread.currentThread().
You haven't explained what exactly you mean with "not working", I assume that you mean that the thread you interrupted still continues to run. That's because, none of the threads is actually performing an operation that is checking the fact if it's interrupted.
You might change your MyThread-implementation this way:
class MyThread extends Thread{
public MyThread(String name) {
super(name);
}
public void run() {
try {
while(true){
Thread.sleep(10);
}
}
catch(InterrutedException ie) {
// leads to the end of the thread
}
}
}
or alternatively
while(!interrupted()){
}
Oh, and wait a bit between interrupting and outputting all Threads. Starting and shutting down threads is a complex task that takes some time. So even with fully functional code that reliably shuts down your Thread, the interrupted one might still show up as active if you list all threads immediately afterwards.
Related
I am learning about the use of semaphores and multi threading in general but am kind of stuck. I have two threads printing G and H respectively and my objective is to alternate the outputs of each thread so that the output string is like this;
G
H
G
H
G
H
Each of the two classes has a layout similar to the one below
public class ClassA extends Thread implements Runnable{
Semaphore semaphore = null;
public ClassA(Semaphore semaphore){
this.semaphore = semaphore;
}
public void run() {
while(true)
{
try{
semaphore.acquire();
for(int i=0; i<1000; i++){
System.out.println("F");
}
Thread.currentThread();
Thread.sleep(100);
}catch(Exception e)
{
System.out.println(e.toString());
}
semaphore.release();
}
}
}
below is my main class
public static void main(String[] args) throws InterruptedException {
Semaphore semaphore = new Semaphore(1);
ClassA clasA = new ClassA(semaphore);
Thread t1 = new Thread(clasA);
ClassB clasB = new ClassB(semaphore);
Thread t2 = new Thread(clasB);
t1.start();
t2.join();
t2.start();
The output I am getting is way too different from my expected result. can anyone help me please? did I misuse the semaphore? any help?
Semaphores can't help you solve such a task.
As far as I know, JVM doesn't promise any order in thread execution. It means that if you run several threads, one thread can execute several times in a row and have more processor time than any other. So, if you want your threads to execute in a particular order you can, for the simplest example, make a static boolean variable which will play a role of a switcher for your threads. Using wait() and notify() methods will be a better way, and Interface Condition will be the best way I suppose.
import java.io.IOException;
public class Solution {
public static boolean order;
public static void main(String[] args) throws IOException, InterruptedException {
Thread t1 = new ThreadPrint("G", true);
Thread t2 = new ThreadPrint("O", false);
t1.start();
t2.start();
t2.join();
System.out.println("Finish");
}
}
class ThreadPrint extends Thread {
private String line;
private boolean order;
public ThreadPrint(String line, boolean order) {
this.line = line;
this.order = order;
}
#Override
public void run() {
int z = 0;
while (true) {
try {
for (int i = 0; i < 10; i++) {
if (order == Solution.order) {
System.out.print(line + " ");
Solution.order = !order;
}
}
sleep(100);
} catch (Exception e) {
System.out.println(e.toString());
}
}
}
}
BTW there can be another problem cause System.out is usually an Operation System buffer and your OS can output your messages in an order on its own.
P.S. You shouldn't inherit Thread and implement Runnable at the same time
public class ClassA extends Thread implements Runnable{
because Thread class already implements Runnable. You can choose only one way which will be better for your purposes.
You should start a thread then join to it not vice versa.
t1.start();
t2.join();
t2.start();
As others have pointed out, locks themselves do not enforce any order and on top of that, you cannot be certain when a thread starts (calling Thread.start() will start the thread at some point in the future, but this might take a while).
You can, however, use locks (like a Semaphore) to enforce an order. In this case, you can use two Semaphores to switch threads on and off (alternate). The two threads (or Runnables) do need to be aware of each other in advance - a more dynamic approach where threads can "join in" on the party would be more complex.
Below a runnable example class with repeatable results (always a good thing to have when testing multi-threading). I will leave it up to you to figure out why and how it works.
import java.util.concurrent.*;
public class AlternateSem implements Runnable {
static final CountDownLatch DONE_LATCH = new CountDownLatch(2);
static final int TIMEOUT_MS = 1000;
static final int MAX_LOOPS = 10;
public static void main(String[] args) {
ExecutorService executor = Executors.newCachedThreadPool();
try {
AlternateSem as1 = new AlternateSem(false);
AlternateSem as2 = new AlternateSem(true);
as1.setAlternate(as2);
as2.setAlternate(as1);
executor.execute(as1);
executor.execute(as2);
if (DONE_LATCH.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
System.out.println();
System.out.println("Done");
} else {
System.out.println("Timeout");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
executor.shutdownNow();
}
}
final Semaphore sem = new Semaphore(0);
final boolean odd;
AlternateSem other;
public AlternateSem(boolean odd) {
this.odd = odd;
}
void setAlternate(AlternateSem other) { this.other = other; }
void release() { sem.release(); }
void acquire() throws Exception { sem.acquire(); }
#Override
public void run() {
if (odd) {
other.release();
}
int i = 0;
try {
while (i < MAX_LOOPS) {
i++;
other.acquire();
System.out.print(odd ? "G " : "H ");
release();
}
} catch (Exception e) {
e.printStackTrace();
}
DONE_LATCH.countDown();
}
}
I am trying to learn how to write a program which performs a given set of tasks in sequence with the help of threads. For example, Writing a program which have 3 different threads print 1111…, 22222…., 333333……, so that the output will be 1,2,3,1,2,3,1,2,3…..? OR for e.g. 2 threads one is printing odd numbers and other even numbers, but the output should be printed in sequence - i.e. one even and then odd.
I would like to learn how to write similar kind of programs in which different threads print different stuff concurrently and the output should be printed in sequence.
What is the basic concept in writing these programs. Can we use ThreadPools/Executors for the purpose ? For e.g. can we use
ExecutorService exectorService = Executors.newFixedThreadPool(3);
Can we use Future, FurtureTask, Callable, execute, submit ...? I know these concepts but I am not able to connect the dots for solving the above scenarios.
Please guide me how to go about writing these kind of programs using multithreading / concurrency.
I have written a program using wait()/notifyAll(). Following is the program. I am not executing the consumer as I am printing the whole sequence at the end. Also I am limiting the capacity of the queue to be 15. So I am basically printing the odd / even range till 15.
public class ProduceEven implements Runnable {
private final List<Integer> taskQueue;
private final int MAX_CAPACITY;
public ProduceEven (List<Integer> sharedQueue, int size) {
this.taskQueue = sharedQueue;
this.MAX_CAPACITY = size;
}
#Override
public void run() {
// TODO Auto-generated method stub
int counter = 0;
while (counter < 15) {
try {
produce(counter++);
} catch (InterruptedException e) {
e.getMessage();
}
}
}
private void produce (int i) throws InterruptedException {
synchronized (taskQueue) {
while (taskQueue.size() == MAX_CAPACITY) {
System.out.println("Queue is full : "+Thread.currentThread().getName()+" is waiting , size: "+ taskQueue.size());
taskQueue.wait();
}
Thread.sleep(1000);
if(i%2==0) {
taskQueue.add(i);
}
taskQueue.notifyAll();
}
}
}
public class ProduceOdd implements Runnable {
private final List<Integer> taskQueue;
private final int MAX_CAPACITY;
public ProduceOdd (List<Integer> sharedQueue, int size) {
this.taskQueue = sharedQueue;
this.MAX_CAPACITY = size;
}
#Override
public void run() {
int counter = 0;
while (counter < 15) {
try {
produce(counter++);
} catch (InterruptedException e) {
e.getMessage();
}
}
}
private void produce (int i) throws InterruptedException {
synchronized (taskQueue) {
while (taskQueue.size() == MAX_CAPACITY) {
System.out.println("Queue is full : "+Thread.currentThread().getName()+" is waiting , size: "+ taskQueue.size());
taskQueue.wait();
}
Thread.sleep(1000);
if(i%2==1) {
taskQueue.add(i);
}
taskQueue.notify();
}
}
}
public class OddEvenExampleWithWaitAndNotify {
public static void main(String[] args) {
List<Integer> taskQueue = new ArrayList<Integer>();
int MAX_CAPACITY = 15;
Thread tProducerEven = new Thread(new ProduceEven(taskQueue, MAX_CAPACITY), "Producer Even");
Thread tProducerOdd = new Thread(new ProduceOdd(taskQueue, MAX_CAPACITY), "Producer Odd");
tProducerEven.start();
tProducerOdd.start();
try {
tProducerEven.join();
tProducerOdd.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
ListIterator listIterator = taskQueue.listIterator();
System.out.println("Elements Are:: ");
while(listIterator.hasNext()) {
System.out.print(listIterator.next()+" ");
}
}
}
The output which I get is: Elements Are:: 02134657911810131214
The output is all jumbled up. Why is it not in sequence. 01234567891011121314 What am I missing. I would be now trying to make the program using Semaphores. Also how do we make this program using explicit locks?
Yes, you can use ExecutorService as a starting point to run your threads. You can also create and start your Threads manually, that would make no difference.
The important thing is that your Threads will run in parallel if you do not synchronize them (i.e., they have to wait for one another). To synchronize you can, e.g. use Semaphores or other thread communication mechanisms.
You wrote in the comments you have written a producer/consumer program. It's a bit of the same thing. Each time the 1-Thread produces a 1, the 2-Thread must know that it can now produce a 2. When it is finished, it must let the 3-Thread know that it must produce a 3. The basic concepts are the same. Just the threads have both producer and consumer roles.
Hi this is one sample program to print Odd and Even using two thread and using thread synchronization among them.
Also we have used Executor framework which is not mandatory, you can create thread using new Thread() as well. For quick prototype I have used system.exit() which can be replaced with graceful shutdown of threads like, interruption and all.
package com.ones.twos.threes;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class OnesTwos {
public static void main(String[] args) {
BlockingQueue<Integer> bq1 = new ArrayBlockingQueue<Integer>(100);
BlockingQueue<Integer> bq2 = new ArrayBlockingQueue<Integer>(100);
ExecutorService executorService = Executors.newFixedThreadPool(2);
try {
bq1.put(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
executorService.submit(new OddEven(bq1, bq2));
executorService.submit(new OddEven(bq2, bq1));
executorService.shutdown();
}
public static class OddEven implements Runnable {
BlockingQueue<Integer> bq1;
BlockingQueue<Integer> bq2;
public OddEven(BlockingQueue<Integer> bq1, BlockingQueue<Integer> bq2) {
this.bq1 = bq1;
this.bq2 = bq2;
}
#Override
public void run() {
while (true) {
try {
int take = bq1.take();
System.out.println(take);
bq2.offer(take + 1);
if (take > 20)
System.exit(0);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
Mycode is also similar to Anirban's, except I am not using executor framework,
public class TestThread {
public static void main(String[] args) {
Boolean bol = new Boolean(true);
(new Thread(new Odd(bol), "odd")).start();
(new Thread(new Even(bol), "even")).start();
}
}
public class Even implements Runnable {
private Boolean flag;
public Even(Boolean b) {
this.flag = b;
}
#Override
public void run() {
for (int i = 2; i < 20; i = i + 2) {
synchronized (flag) {
try {
System.out.println(Thread.currentThread().getName()+":"+i);
Thread.sleep(1000);
flag.notify();
flag.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public class Odd implements Runnable {
private Boolean flag;
public Odd(Boolean b) {
this.flag = b;
}
#Override
public void run() {
for (int i = 1; i < 20; i = i + 2) {
synchronized (flag) {
try {
System.out.println(Thread.currentThread().getName()+":"+i);
Thread.sleep(1000);
flag.notify();
flag.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
By establishing the thread pool of 3 (ExecutorService exectorService = Executors.newFixedThreadPool(3); you are essentilly limiting the executor capacity to 3 and other incoming threads will be on hold. If you want to run them in paralel you can just submit them at once. If you want to wait for each other and want to find out the result I suggest you use Callable. Personally I really like Callable because after submiting it you can just call the get method of Future, wait for a returned value from the executed thread and then continue to the next one. From the API you can see this:
/**
* Submits a value-returning task for execution and returns a
* Future representing the pending results of the task. The
* Future's {#code get} method will return the task's result upon
* successful completion.
*
*
* If you would like to immediately block waiting
* for a task, you can use constructions of the form
* {#code result = exec.submit(aCallable).get();}
And a very good example here. If you go for the Callable alternative then you don't need a Thread pool. Just a normal executor is fine. Remember to shut the executor down in the end.
class MyNumber {
int i = 1;
}
class Task implements Runnable {
MyNumber myNumber;
int id;
Task(int id, MyNumber myNumber) {
this.id = id;
this.myNumber = myNumber;
}
#Override
public void run() {
while (true) {
synchronized (myNumber) {
while (myNumber.i != id) {
try {
myNumber.wait(); //Wait until Thread with correct next number
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(id);
if (myNumber.i == 1) {
myNumber.i = 2;
} else if (myNumber.i == 2) {
myNumber.i = 3;
} else {
myNumber.i = 1;
}
myNumber.notifyAll();
}
}
}
}
In main method:
MyNumber myNumber = new MyNumber();
new Thread(new Task(1, myNumber)).start();
new Thread(new Task(2, myNumber)).start();
new Thread(new Task(3, myNumber)).start();
Hi here we have used 2 thread one to print even and another to print odd.
Both are separate and have no relation to each other.
But we have to do a synchronization mechanism between them. Also we need a mechanism to let the ball rolling, i.e. start one thread printing.
Each thread is waiting on condition and after doing it's task it lets other thread work and put ownself in waiting state.
Well happy path works fine, but we need special care when even thread is not in waiting state and the signal() from main fires, in that case even thread will never able to wake up and the program hangs.
So to make sure main thread successfully sends a signal() to even thread and even thread does not miss that we have used Phaser(with party) and checking even thread state in while loop in main.
Code is as below.
package com.ones.twos.threes;
import java.util.concurrent.Phaser;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class OnesTwosTrial2 {
public static void main(String[] args) {
Lock lk = new ReentrantLock();
Phaser ph = new Phaser(3); // to let main start the even thread
Condition even = lk.newCondition();
Condition odd = lk.newCondition();
OnesTwosTrial2 onestwostrial2 = new OnesTwosTrial2();
Thread ev = onestwostrial2.new Evens(lk, even, odd, ph);
Thread od = onestwostrial2.new Odds(lk, even, odd, ph);
ev.start();
od.start();
System.out.println("in main before arrive");
ph.arriveAndAwaitAdvance();
System.out.println("in main after arrive");
// we have to make sure odd and even thread is
// started and waiting on respective condition.
// So we used Phaser with 3, because we are having here
// 3 parties (threads)
// main, odd,even. We will signal only when all the
// threads have started.
// and waiting on conditions.
while (!Thread.State.WAITING.equals(ev.getState())) {
System.out.println("waiting");
}
lk.lock();
even.signal();
lk.unlock();
}
class Evens extends Thread {
Lock lk;
Condition even;
Condition odd;
Phaser ph;
public Evens(Lock lk, Condition even, Condition odd, Phaser ph) {
this.lk = lk;
this.even = even;
this.odd = odd;
this.ph = ph;
}
#Override
public void run() {
System.out.println("even ph");
int cnt = 0;
while (cnt < 20) {
try {
lk.lock();
ph.arrive();
even.await();
System.out.println(cnt);
cnt += 2;
odd.signal();
lk.unlock();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Odds extends Thread {
Lock lk;
Condition even;
Condition odd;
Phaser ph;
public Odds(Lock lk, Condition even, Condition odd, Phaser ph) {
this.lk = lk;
this.even = even;
this.odd = odd;
this.ph = ph;
}
#Override
public void run() {
System.out.println("odd ph");
int cnt = 1;
while (cnt < 20) {
try {
lk.lock();
ph.arrive();
odd.await();
System.out.println(cnt);
cnt += 2;
even.signal();
lk.unlock();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
package threadShareResource1;
public class NonSynchro1 {
private int sum = 0;
public static void main(String[] args) {
NonSynchro1 n = new NonSynchro1();
n.task();
System.out.println(n.getSum());
}
public synchronized void sumAddOne(){
sum++;
}
public void task(){
for (int i = 0; i < 100; i++) {
new Thread(new Runnable(){
#Override
public void run() {
sumAddOne();
}
}).start();
/* try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
} */
}
}
public int getSum() {
return sum;
}
}
Without the commented part of code, the program has data corruption, which is not 100 every time I run it. But I thought the synchronized keyword should acquires a lock on the sumAddOne method, which is the critical region of my program, allowing one thread accessing this method every time.
I've try to use ExecutorService as well, but it doesn't give 100 all the runs.
public void task(){
ExecutorService s = Executors.newCachedThreadPool();
for (int i = 0; i < 100; i++) {
s.execute(new Thread(new Runnable(){
#Override
public void run() {
sumAddOne();
}
}));
}
s.shutdown();
while(!s.isTerminated()){}
}
In Task(), you start 100 threads (which is a lot) and each one is to add 1 to sum.
But when Task is done all you know is that 100 threads are in some process of having started. You don't block before calling println(), so how do you know all the threads have completed?
The sleep probably "prevents the corruption" just because it gives the system time to finish launching all the threads.
Beyond that you are using Synchronized correctly. Any place multiple threads may write to the same variable you need it and, in general (simplifying), you don't need it if you are only reading.
Synchronised keyword is used correctly, the problem is that you are not waiting for the threads to finish. Here is a possible solution:
public class NonSynchro1 {
private static final ExecutorService executorService = Executors.newCachedThreadPool();
private int sum = 0;
public static void main(String[] args) {
NonSynchro1 n = new NonSynchro1();
n.task();
System.out.println(n.getSum());
executorService.shutdown();
}
public synchronized void sumAddOne() {
sum++;
}
public void task() {
List<Callable<Object>> callables = new ArrayList<>();
for (int i = 0; i < 100; i++) {
callables.add(() -> {
sumAddOne();
return null;
});
}
List<Future<Object>> futures;
try {
futures = executorService.invokeAll(callables);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
futures.forEach(future -> {
try {
future.get();
} catch (ExecutionException | InterruptedException e) {
throw new RuntimeException(e);
}
});
}
public int getSum() {
return sum;
}
}
First we create a list of callables - a list of functions that will be executed in parallel.
Then we invoke them on the executor service. newCachedThreadPool I have used here, by default has 0 threads, it will create as many as necessary to execute all passed callables, the threads will be killed after being idle for a minute.
Finally, in the for-each loop we resolve all futures. get() call will block until the function was executed by the executor service. It will also throw exception if it was thrown inside the function (without calling get() you would not see such exception at all).
Also, it is a good idea to shutdown the executor service when you want to terminate the program gracefully. In this case, it is just executorService.shutdown() at the end of main method. If you don't do this, the program will terminate after a minute when idle threads are killed. However, if different executor service, threads might not be killed when idle, in which case the program would never terminate.
Just for completeness sake: Here's a solution showing how the original program can be made to wait for all threads to finish by joining them:
for (Thread t : n.task())
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
which requires task to return the threads it creates. In this case we don't need to complicate things with caching managers or collections: a simple array will do. Here's the complete class:
public class TestSynchro1 {
private int sum = 0;
public synchronized void sumAddOne() {
sum++;
}
public Thread[] task(int n) {
Thread[] threads = new Thread[n];
for (int i = 0; i < n; i++) {
(threads[i] = new Thread(new Runnable() {
#Override
public void run() {
sumAddOne();
}
})).start();
}
return threads;
}
public static void main(String[] args) {
TestSynchro1 n = new TestSynchro1();
for (Thread t : n.task(100))
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(n.sum);
}
}
I thought I might be able to do it by trying something like this, but it doesn't work:
Thread[] threads = new Thread[myNumThreads];
for (int i=0; i<myNumThreads; i++) {
threads[i] = new Thread () {
#Override
public void run() {
<Code to do when running>
}
//CODE I TRIED TO ADD:
public boolean getValue(){
return true;
}
};
}
Basically instead of calling join() to end a thread I want a way to get a thread to do something and return some data to the main method while still running.
When you run code, it always uses the current thread. If the code is attached to another thread object, e.g. Thread.join(); it is still the current thread which waits while the background thread runs.
The simplest way to get another thread to do work is to use an ExecutorService
ExecutorService es = Executors.newFixedThreadPool(myNumThreads);
List<Future<ResultType>> futures = new ArrayList<>();
for (int i = 0; i < myNumThreads; i++) {
futures.add(es.submit(new Callable<Result>() {
public ResultType call() {
// do something
return result;
}
});
}
// do something while the thread task executes
for (Future<ResultType> future: futures) {
ResultType result = future.get();
}
// when finished with the pool
es.shutdown();
Its hard to figure out what you mean by "it doesn't work" but I think you might just missing a call to
threads[i].start();
If however you want to be able to call the getValue() method from outside of the class then you will need to create a new MyThread class which extends Thread and use that type instead of thread:
class MyThread extends Thread {
#Override
public void run() {
for (int j=0 ; j< 10; j++) {
System.out.println("working:" + j + ":" + this.getValue());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//CODE I TRIED TO ADD:
public boolean getValue(){
return true;
}
}
And then call it as follows:
int myNumThreads = 10;
MyThread[] threads = new MyThread[myNumThreads];
for (int i=0; i<myNumThreads; i++) {
threads[i] = new MyThread () ;
threads[i].start();
}
System.out.println(threads[0].getValue());
You can try to write your own Thread: Like "MyThread extends Thread"
I am currently working on a project where I am to have essentially 10 threads that are "sleeping". At random one of these 10 threads is to "wake up" and start doing some work. I just want to see if I am headed in the right direction. So should I just create each instance of the thread for instance.
Thread thread0 = new Thread(new doWork());
...
Thread thread9 = new Thread(new doWork());
and just not start them and then when they are to "wake" just call the start() method on the particular thread..
or should I start each thread but have them wait() until I call the notify() method?
or should I start the thread and use sleep() and then call the interrupt() method?
Which approach seems to be better and why?
Any insight is greatly appreciated.
edit Will this be acceptable??
import java.util.Random;
public class Client {
private static Thread [] clients = new Thread[10];
public static void main(String[] args){
createClients();
randomWake();
}// end main()
static void createClients(){
Thread client0 = new Thread(new ClientThread(0));
clients[0] = client0;
Thread client1 = new Thread(new ClientThread(1));
clients[1] = client1;
Thread client2 = new Thread(new ClientThread(2));
clients[2] = client2;
Thread client3 = new Thread(new ClientThread(3));
clients[3] = client3;
Thread client4 = new Thread(new ClientThread(4));
clients[4] = client4;
Thread client5 = new Thread(new ClientThread(5));
clients[5] = client5;
Thread client6 = new Thread(new ClientThread(6));
clients[6] = client6;
Thread client7 = new Thread(new ClientThread(7));
clients[7] = client7;
Thread client8 = new Thread(new ClientThread(8));
clients[8] = client8;
Thread client9 = new Thread(new ClientThread(9));
clients[9] = client9;
for(int i = 0; i < clients.length; i++)
clients[i].start();
}// end createClients()
static void randomWake(){
Random rand = new Random();
int randomNumber = rand.nextInt(10);
clients[randomNumber].interrupt();
}// end randomWake()
static class ClientThread implements Runnable{
private int clientNumber;
public ClientThread(int clientNumber){
this.clientNumber = clientNumber;
}// end ClientThread(int clientNumber)
public void run(){
while(!Thread.interrupted()){}
System.out.println("Client " + clientNumber + " is awake!");
}// end run()
}// end class ClientThread
}// end class Client
In case there is a maximum amount of sleep time
You probably will need to implement the following Thread class:
public class DoWork extends Thread {
public void run () {
while(true) {
Thread.Sleep((int) Math.floor(Math.random()*10000));
//do some work
}
}
}
Where 10000 is the maximum time in milliseconds a thread should sleep.
In case there is no maximum amount of sleep time
You probably will need to implement the following Thread class:
public class DoWork extends Thread {
public void run () {
while(true) {
Thread.Sleep(1);
if(Math.random() < 0.005d) {
//do some work
}
}
}
}
where 0.005 is the probability of running the method a certain millisecond.
notify and wait are used to implement Semaphores: this are objects that prevent two threads to manipulate the same object at the same time (since some objects could end up in an illegal state).
How about using semaphores?
class DoWork extends Runnable {
private final Semaphore semaphore;
DoWork(Semaphore semaphore) {
this.semaphore = semaphore;
}
#Override
public void run() {
while (true) {
semaphore.acquire();
//do some work
}
}
}
The main program can create an array of Semaphores, and an equal number of Threads running DoWork instances, so that each DoWork instance has its own semaphore. Each time the main program calls sema[i].release(), The run() method of the corresponding DoWork instance will "do some work" and then go back to waiting.
It doesn't make much sense your answer, so not sure what you really want to achieve. But for what you describe you should put all threads waiting on the same lock and just notify the lock (it will awake only one randomly)
But as that doesn't make much sense, I guess you want to achieve something different.
Check this question regarding sleep vs wait: Difference between wait() and sleep()
Check this one. This is how I would solve it if I were not to use ThreadPooling (which is very correct as the others have said) and so that I can see how wait(),notify() and Thread.sleep() work. Checking google you will see (e.g. Thread.sleep and object.wait) that the mainly wait() and notify() are used for communication between threads and Thread.sleep is used so that you can pause your program.
-Part of this answer is based on this: http://tutorials.jenkov.com/java-concurrency/thread-signaling.html#missedsignals. You can check in the code to see the steps that you need to take (comment out some parts of the code) in order to make your program hang, so that you realize how to work with missed signals. The iterations needed for your program to hang are not fixed.
-The programm will run forever. You will need to work on it a bit in order to fix that.
Main
public class Main
{
public static void main(String[] args)
{
Manager mgr = new Manager("manager");
mgr.start();
}
}
Manager
public class Manager extends Thread
{
private final Object lock = new Object();
private boolean wasSignalled = false;
private DoWork[] workThreads = new DoWork[5];
public Manager(String name){
super(name);
workThreads[0] = new DoWork(this,"work 0");
workThreads[1] = new DoWork(this,"work 1");
workThreads[2] = new DoWork(this,"work 2");
workThreads[3] = new DoWork(this,"work 3");
workThreads[4] = new DoWork(this,"work 4");
}
public void wakeUP()
{
synchronized (this.lock) {
wasSignalled = true;
this.lock.notify();
}
}
public void pauseAndWait()
{
synchronized (this.lock) {
if(!wasSignalled)
{
try {
this.lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//clear signal and continue running.
wasSignalled = false;
}
}
public void run ()
{
int i=0;
while(true)
{
i++;
System.out.println(" manager ...: "+i+" ");
int choose = 0 + (int)(Math.random() * ((4 - 0) + 1));
//choose=0; for debugginng
if(!workThreads[choose].isAlive()){
workThreads[choose].start();
}
else{
workThreads[choose].wakeUP();
}
//wait to be notified by DoWork thread when its job
//is done
pauseAndWait();
}
}
}
DoWork
public class DoWork extends Thread
{
private final Object lock = new Object();
private boolean wasSignalled = false;
private Manager managerThread;
public DoWork(Manager managerThread,String name){
super(name);
this.managerThread=managerThread;
}
public void wakeUP()
{
synchronized (this.lock) {
//check what happens without wasSignalled flag
//step #1: comment out wasSignalled = true;
wasSignalled = true;
this.lock.notify();
}
}
public void pauseAndWait()
{
synchronized (this.lock) {
//check what happens without wasSignalled flag
//step #2: comment out the if block
if(!wasSignalled)
{
try {
this.lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//check what happens without wasSignalled flag
//step #3: comment out wasSignalled = false;
//clear signal and continue running.
wasSignalled = false;
}
}
public void run ()
{
int i=0;
while(true)
{
i++;
try {
System.out.print(this.getName()+" going to sleep ...: "+i+" ");
//check what happens without wasSignalled flag
//step #4: put sleep time to Thread.sleep(0);
//simulate worker thread job
Thread.sleep(1000);
System.out.println(" woke up ... ");
} catch (InterruptedException e) {
System.out.println(" worker thread: job simulation error:"+e);
}
//if worker thread job simulation is done (sleep for 4 times)
//then suspend thread and wait to be awaken again
if(i>4)
{
System.out.println(this.getName()+" notifying main ...: "+i+" \n");
i=0;
managerThread.wakeUP();
// thread does not get destroyed, it stays in memory and when the manager
// thread calls it again it will wake up do its job again
pauseAndWait();
}
}
}
}