Synchronized keyword doesn't work - java

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);
}
}

Related

Ending console based multi threaded program gracefully

I have the following class, I usually run about 10 threads of it
public class MyClass implements Runnable {
private volatile Device device = null;
public MyClass(Device device) {
this.device = device;
}
#Override
public void run() {
while (true) { // <--- I do know that the "true" has to be changed to a Boolean
try {
Worker worker = new Worker();
worker.work();
System.out.println("Waiting 6 seconds!");
Thread.sleep(6 * 1000);
System.out.println("------------------------------------");
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println("Thread in program ended!");
}
}
and in my main I start the threads like this
for (int i = 0; i < 2; i++) {
(new Thread(new MyClass())).start();
}
This is a console based program. What is the most reliable way to end the program? I think the best way would be to change while (true) to while (Boolean) and somehow change that Boolean for all threads, then when the loop ends, the program will end gracefully.
Here i'm ending it by waiting for a user input but you can change it to fire the stop method from anywhere
public static void main(String[] args) {
List<MyClass> myThreads = new ArrayList<>();
for (int i = 0; i < 2; i++) {
MyClass myClass = new MyClass();
Thread t = new Thread(myClass);
t.start();
myThreads.add(myClass);
}
Scanner in = new Scanner(System.in);
in.next();
for(MyClass t : myThreads){
t.stop();
}
}
class MyClass implements Runnable {
private Boolean flag;
public MyClass() {
this.flag = true;
}
#Override
public void run() {
while (flag) { // <--- I do know that the "true" has to be changed to a Boolean
try {
System.out.println("Waiting 6 seconds!");
Thread.sleep(6 * 1000);
System.out.println("------------------------------------");
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println("Thread in program ended!");
}
public void stop(){
this.flag = false;
} }
The easy way would be to store all your threads in a set and make loop joining them at the end.
Be aware that this is not the most ortodox neither the most efficient way to do this.
In your main:
HashSet<Thread> threads = new HashSet();
for (int i = 0; i < 2; i++) {
Thread t = new Thread(new MyClass());
threads.add(t);
t.start();
}
for (Thread thread: threads) {
thread.join();
}
some more material
The following code uses an executor service to fix the number of threads that run at any time, it provides a Future object that also tells you when your thread has shutdown gracefully. They share a shutdown object as well. This offers you a bit more flexibility as the executor service can let you decide how many threads run at any one time gracefully.
First lets created a shared shutdown object that will notify all the threads it is time to shut down. There will be one instance of this and each thread will have a copy.
public static class Shutdown {
private boolean running;
public void shutdown() {
this.running = false;
}
public boolean isRunning() {
return running;
}
}
Next let me just create a dummy thread that does nothing more than sleep forever while it is running. Obviously you can simply replace this with your own thread to do something useful.
public static class MyClass implements Runnable {
final Shutdown shutdown;
public MyClass(Shutdown shutdown) {
this.shutdown = shutdown;
}
#Override
public void run() {
while (shutdown.isRunning()) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
System.out.println("Did not gracefully shut down");
}
}
System.out.println("Thread in program ended!");
}
}
}
Now for the main class which will run everything, this is where the magic happens.
public class Main {
public static void main(String[] args) {
//run exactly 10 threads at a time
ExecutorService executorService = Executors.newFixedThreadPool(10);
//this is how we shut it down
Shutdown globalShutdown = new Shutdown();
//start up the 10 threads
List<Future<?>> futures = new ArrayList<>();
for(int i = 0; i< 10; i++)
futures.add(executorService.submit(new MyClass(globalShutdown)));
//gracefully shut them down
globalShutdown.shutdown();
try {
//wait for them all to shutdown
for(Future<?> future : futures)
future.get();
} catch (InterruptedException e) {
throw new IllegalStateException("This should never happen");
} catch (ExecutionException e) {
throw new IllegalStateException("This should never happen");
}
//everything got shutdown!
}
in practice however you probably also want to handle the case where your thread may not end gracefully due to a bug. Rather than stall forever you might want to add a timeout and if that timeout is exceeded then simply forcibly terminate all remaining threads. To do that replace the above try-catch block with this.
try {
//wait for them all to shutdown
boolean timedout = false;
for(Future<?> future : futures) {
if( !timedout ) {
try {
future.get(30, TimeUnit.SECONDS);
} catch (TimeoutException e) {
timedout = true;
}
}
if(timedout) {
future.cancel(true);
}
}
} catch (InterruptedException | ExecutionException e) {
throw new IllegalStateException("This should never happen");
}

Threading in Sequence

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();
}
}
}
}
}

Java: How to put thread back to sleep INDEFINITELY after interrupt?

I am writing Java software, that has a single thread, which listens to external buttons being pressed. If the button is pressed, the thread informs other threads, but otherwise it just sleeps.
My model is to use interrupt-driven design. Ideally I would like to make
a thread sleep as long as no button is pressed. When the button is pressed I would like the thread to do some work and go back to sleep.
Could anyone confirm / correct the following implementation?
// This is a code that interrupt-driven thread will execute
public void run() {
while (true) {
try {
Thread.sleep(1000); // Sleeps only for 1s. How to sleep indefinitely?
} catch (InterruptedException exception) {
process(exception); // Doing some work
// then going back to sleep using the while loop
}
}
}
Also, after each button click in the terminal I get a message
I/O exception raised from stop()
What does this message mean (i.e why is it printed if I catch the exception)? Can I avoid the terminal to print it?
It is generally considered a code smell if you use exceptions to control your program flow.
The correct solution to this problem is to use a BlockingQueue of events that the event handler reads from. This is commonly called a producer/consumer.
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 BlockingQueue<Integer> queue;
public Producer(BlockingQueue<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 BlockingQueue<Integer> queue;
public Consumer(BlockingQueue<Integer> queue) {
this.queue = queue;
}
#Override
public void run() {
boolean ended = false;
while (!ended) {
try {
Integer i = queue.take();
ended = i == End;
System.out.println(i);
} catch (InterruptedException ex) {
ended = true;
}
}
}
}
public void test() throws InterruptedException {
BlockingQueue<Integer> 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();
}
}
Don't let yourself be confused by how much code this is - most of it is just wrapping. The core functionality is:
At start - create a BlockingQueue and share it between the two threads.
BlockingQueue<Integer> queue = new LinkedBlockingQueue<>();
Thread pt = new Thread(new Producer(queue));
Thread ct = new Thread(new Consumer(queue));
When an event happens, post to the queue.
queue.add(i);
The event handler feeds off the queue.
while (!ended) {
try {
Integer i = queue.take();
Note that take here will block until an event is posted or an interrupt occurrs.
You can use
Thread.sleep(Long.MAX_VALUE); // more than the life of your computer
or
synchronized(this) {
wait();
}
or this wake on interrupt but doesn't throw an exception
LockSupport.park();
However a more elegant solution is likely to be to use an ExecutorService is designed to be a sleeping thread pool which wakes when you give it work to do.
ExecutorsService executor = Executors.newSingleThreadExecutor();
// when you want it to do something
executor.submit(this::process);
Note: you should consider how you want to handle exceptions. In the example in your question, an exception or error will kill the thread and it will stop running. In my example it won't kill the thread pool but the actual exception could be lost. For this reason I suggest you write it like this.
executor.submit(() -> {
try {
process();
} catch(Throwable t) {
LOGGER.warning(t);
}
});
Note: instead of just calling process and it having to figure out what you want to do you can write it like this.
doSomething(string, number, pojo);
That way you can see what data you expect the background thread to work on.
For comparison, here is the TwoThread example using the current thread as a producer and an Executor Service.
public class TwoThreadsJava5 {
public static void main(String args[]) throws InterruptedException {
System.out.println("TwoThreads:Test - Java 5.0 style");
ExecutorService executor = Executors.newSingleThreadExecutor();
for (int i = 0; i < 1000; i++) {
final int finalI = i;
executor.submit(() -> {
try {
System.out.println(finalI);
} catch (Throwable t) {
t.printStackTrace();
}
});
}
executor.shutdown();
executor.awaitTermination(1, TimeUnit.MINUTES);
}
}
And in Java 8 you could write
public class TwoThreadsJava8 {
public static void main(String args[]) throws InterruptedException {
System.out.println("TwoThreads:Test - Java 8 style");
IntStream.range(0, 1000)
.parallel()
.forEach(System.out::println);
}
}

why object.wait(value) is not accurate?

consider this code which basically has an object(WaitedObject) and two threads(SomeTask and SomeTaskWithWait) compete to call the methods (longRunningTask() and withWaitTask() respectively) of the object synchronously
package closerLookAtWait;
class WaitedObject
{
int i=0;
synchronized void longRunningTask()
{
System.out.println(i++);
for(long j=999; j>0; j--)
{}
}
synchronized void withWaitTask()
{
System.out.println("Now Waiting");
long time1 = System.currentTimeMillis();
try {
//Thread.sleep(500);
wait(50);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
long time2 = System.currentTimeMillis() - time1;
System.out.println("Done Waiting for "+time2);
}
}
class SomeTask implements Runnable
{
WaitedObject wo;
SomeTask(WaitedObject wo)
{
this.wo = wo;
}
#Override
public void run() {
while(true)
wo.longRunningTask();
}
}
class SomeTaskWithWait implements Runnable{
WaitedObject wo;
SomeTaskWithWait(WaitedObject wo)
{
this.wo = wo;
}
#Override
public void run() {
while(true)
wo.withWaitTask();
}
}
public class SomeWaitingWithLong {
public static void main(String[] args) {
WaitedObject wo = new WaitedObject();
new Thread(new SomeTask(wo)).start();
new Thread(new SomeTaskWithWait(wo)).start();
}
}
sample output:
well i got output as 54,54,50,65,51,52,..,78,..84,..50,52,52.
now my question is why such inaccuracy? (even 65 is ok, but why 84?)
One of the reasons is, OS puts that thread in suspended mode for the time(ms) you provide in wait(). When the time completes it isn't guarrented that your thread will be executed at once because OS has assigned another thread with a higher priority in your process to be executed by the processor or some other higher priority process is being assigned to the processor for execution. Even if your thread was at highest priority, even then there will be some delay sometimes because of context switching & in Java's case, GC.
Simple answer: Android is not a real time OS.

How do I test the completion of threads created under my testmethod in JUnit

I have a method createThreads which spawns few new threads. Each of the newly created thread does some work. If I invoke the method `createThreads' in junit, how can i ensure that all the newly spawned threads have also completed successfully.
I am currently calling as below
#Test
public void test() {
createThreads(); // Does not wait until the newly created threads also finish.
}
public void createThreads()
{
ExecutorService executorService = Executors
.newFixedThreadPool(numThreads);
for (int i = 0; i < numThreads; i++) {
executorService.execute(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("I have completed execution " + Thread.currentThread().getName());
}
});
}
Note that I cannot modify createThreads
a bit odd but..
you can probably get all the runing threads
through Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
then filter it to identify the thread from the executor service.
then do a .join() on each of those threads.
as i said, a bit odd but it should fit your needs ...
try running this, you'll see that they are quite easy to identify :
public static void main(String[] args) {
int nb = 3;
ExecutorService executorService = Executors.newFixedThreadPool(nb);
for (int i = 0; i < nb; i++) {
executorService.execute(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("I have completed execution " + Thread.currentThread().getName());
}
});
}
Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
for (Thread t : threadSet) {
System.out.println(t.getName());
}
}
sorry for a 2nd answer not possible to add such a long code in comment

Categories

Resources