I have a volatile int variable with value 0 that I want to increase up to 100 using 5 thread. I am trying to generate result from 0 to 100 with no duplicate. Can anyone please help me to resolve this.
I try this approach. Is it proper?
public class Producer implements Runnable {
VolatileIncrement vo = null;
String str = null;
Producer(VolatileIncrement vo, String str){
this.vo = vo;
this.str = str;
}
#Override
public void run() {
while(vo.i < 100){
System.out.println(str+vo.increaseI());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class VolatileIncrement {
volatile Integer i = 0;
public synchronized int increaseI() {
i++;
return i;
}
}
}
public class ProducerMain {
public static void main(String[] args) {
VolatileIncrement vo = new VolatileIncrement();
Producer p1 = new Producer(vo,"I am thread 1 - ");
new Thread(p1).start();
Producer p2 = new Producer(vo,"I am thread 2 - ");
new Thread(p2).start();
Producer p3 = new Producer(vo,"I am thread 3 - ");
new Thread(p3).start();
Producer p4 = new Producer(vo,"I am thread 4 - ");
new Thread(p4).start();
Producer p5 = new Producer(vo,"I am thread 5 - ");
new Thread(p5).start();
}
}
You can use atomic1 classes for the update an integer by multi-threads
AtomicLong counter = new AtomicLong(0);
counter.getAndIncrement();
It is lock-free and thread-safe on single variable.
int counter=0;
public static synchronized void increase()
{
counter++;
}
Call this method.. Since its declared synchronized only one thread will act at a time (i.e. increment at a time).
a) there is no reason to use volatile if all accesses to that variable is within a synchronized block. Synchronized has a larger scope than volatile for syncing memory between threads.
b) you cannot make a simple i++ atomic; you need synchronization, or reentrant locks, or the said AtomicInteger.
Related
I'm currently working on a problem where I have to:
Write out a letter, x amount of times, after x amount of ms. Use 4 multithreads, 3 of them start right away 1 of them starts when one of the 3 is finished.
For example: A, 10, 100, has to write out A ever 10 times every 100 miliseconds.
Im currently stuck on syncing the multithreads for them to work together at adding one sum rather than them working seporatley. Could you advise how to sync it together for it to write out the above?
Here is my code:
public class PrinterThread extends Thread {
private String letter;
private int internal;
private int amount;
public PrinterThread() {
for (int i = 1; i <= internal; i++) {
System.out.println(letter);
}
synchronized (this){
internal++;
}
try {
Thread.sleep(amount);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class Main {
public static void main(String[] args) {
PrinterThread printerThread = new PrinterThread();
PrinterThread printerThread1 = new PrinterThread();
PrinterThread printerThread2 = new PrinterThread();
PrinterThread printerThread3 = new PrinterThread();
printerThread.run();
printerThread1.run();
printerThread2.run();
printerThread3.run();
}
}
Use a BlockingQueue for synchronisation, but you do need to join with the threads from your main method otherwise your main will exit the JVM before the threads finish (or possibly even before they start).
public class PrinterThread implements Runnable {
private String letter;
private int copies;
private int amount;
public PrinterThread(String letter, int copies, int amount) {
this.letter = letter;
this.copies = copies;
this.amount = amount;
}
public void run() {
for (int i = 0; i < copies; i++) {
System.out.println(letter.repeat(copies));
try {
Thread.sleep(amount);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
QUEUE.offer(0);
}
}
public class Main {
private static BlockingQueue<Integer> QUEUE = new ArrayBlockingQueue<>(4); // at least as large as the number of threads
public static void main(String[] args) {
Thread printerThread1 = new Thread(new PrinterThread("A", 10, 100));
Thread printerThread2 = new Thread(new PrinterThread("B", 20, 50));
// etc
printerThread1.start();
printerThread2.start();
// etc
QUEUE.take(); // blocking call
new Thread(new PrinterThread("D", 30, 80)).start();
// wait for threads to finish
printerThread1.join();
printerThread2.join();
// etc
}
}
Disclaimer: This answer was thumbed in via my phone, so it may not work correctly or even compile, but there’s a good chance it will work.
Write out a letter, x amount of times, after x amount of ms. Use 4 multithreads, 3 of them start right away 1 of them starts when one of the 3 is finished.
You obviously need to create a PrinterThread constructor which takes the letter, the amount of times, and amount of millis.
I'm currently stuck on syncing the multithreads for them to work together at adding one sum rather than them working separately.
I'm not sure about the sum. If you are asking how you can start the 3rd thread then there are a number of different ways to do this. I would lock on a lock object and pass in a boolean in the constructor about whether or not the thread should wait() on the lock. As each of the other threads finish they would call notify() on the lock.
private static final Object lock = new Object();
...
public class PrinterThread {
public PrinterThread(char letter, int times, int millis, boolean waitForOthers) {
this.letter = letter;
this.times = times;
this.millis = millis;
if (waitForOthers) {
synchronized (lock) {
// wait for one of the others to notify us
lock.wait();
}
}
}
public void run() {
...
synchronized (lock) {
// notify the lock in case another thread is waiting
lock.notify();
}
}
Then start 3 PrinterThreads with a value of false and 1 of them with a value of true so that it waits.
I am trying to learn volatile field modifier in multi-threading. I came across this statement:
Volatile is preferred in cases when one thread reads and writes a shared variable and other threads just read the same. Whereas if there are more than 2 threads performing read and write both on the shared variable then only volatile is not enough, you need to have synchronization as well.
I am aware that volatile provides visibility and happens-before guarantee, but is it possible to give a simple small example of code to demonstrate the above statements wherein a synchronized block is needed?
public class TwoInts {
private volatile int i1;
private volatile int i2;
public void set(int i1, int i2) {
this.i1 = i1;
this.i2 = i2;
}
public boolean same() {
return i1 == i2;
}
}
Now, if you have one thread doing this:
while (true) {
twoInts.set(i, i);
i++;
}
and a second thread doing this:
while (true) {
if (!twoInts.same()) {
System.out.println("Ooops!!");
}
}
then you will observe the problem that the quoted text is talking about. And if you rewrite the TwoInts class to make the methods synchronized then the "Oooops!!" messages will stop.
Let's say you have int i and two threads, you expect every one read i and set i = i + 1.
Like this:
public class Main {
private static volatile int i = 0;
public static void main(String[] args) throws Exception{
Runnable first = new Runnable() {
#Override
public void run() {
System.out.println("Thread_1 see i = " + i);
i++;
System.out.println("Thread_1 set i = " + i);
}
};
Runnable second = new Runnable() {
#Override
public void run() {
System.out.println("Thread_2 see i = " + i);
i++;
System.out.println("Thread_2 set i = " + i);
}
};
new Thread(first).start();
new Thread(second).start();
}
}
The result is:
Thread_1 see i = 0
Thread_2 see i = 0
Thread_1 set i = 1
Thread_2 set i = 2
As you see, Thread_2 get 0 and set 2(because Thread_1 has updated i to 1), which is not expected.
After adding syncronization,
public class Main {
private static volatile int i = 0;
public static void main(String[] args) throws Exception{
Runnable first = new Runnable() {
#Override
public void run() {
synchronized (Main.class) {
System.out.println("Thread_1 see i = " + i);
i++;
System.out.println("Thread_1 set i = " + i);
}
}
};
Runnable second = new Runnable() {
#Override
public void run() {
synchronized (Main.class) {
System.out.println("Thread_2 see i = " + i);
i++;
System.out.println("Thread_2 set i = " + i);
}
}
};
new Thread(first).start();
new Thread(second).start();
}
}
It works:
Thread_2 see i = 0
Thread_2 set i = 1
Thread_1 see i = 1
Thread_1 set i = 2
There are a lot of such examples... Here's one:
volatile int i = 0;
// Thread #1
while (true) {
i = i + 1;
}
// Thread #2
while (true) {
Console.WriteLine(i);
}
In this case, Thread #1 and Thread #2 are both reading the variable i, but only Thread #1 is writing to it. Thread #2 will always see an incrementing value of i.
Without the volatile keyword, you will occasionally see strange behavior, usually on multiprocessor machines or multicore CPUs. What happens (simplifying slightly here) is that Thread #1 and #2 are each running on their own CPU and each gets it's own copy of i (in it's CPU cache and/or registers). Without the volatile keyword, they may never update each other about the changed value.
Contrast with this example:
static volatile int i = 0;
// Thread #1
while (true) {
i = i + 1;
}
// Thread #2
while (true) {
if (i % 2 == 0)
i == 0;
else
Console.WriteLine(i);
}
So here, Thread #1 is trying to monotonically increment i, and Thread #2 is either going to set i to 0 (if i is even) or print it to the console if i is odd. You would expect that Thread #2 could never print an even number to the console, right?
It turns out that that is not the case. Because you have no synchronization around the access to i, it is possible that Thread #2 sees an odd value, moves to the else branch, and then Thread #1 increments the value of i, resulting in Thread #2 printing an even number.
In this scenario, one way of addressing the problem is to use basic locking as a form of synchronization. Because we cannot lock on a primitive, we introduce a blank Object to lock on:
static volatile int i = 0;
static Object lockOnMe = new Object();
// Thread #1
while (true) {
lock (lockOnMe) {
i = i + 1;
}
}
// Thread #2
while (true) {
lock (lockOnMe) {
if (i % 2 == 0)
i == 0;
else
Console.WriteLine(i);
}
}
I am new in concurrent threads in java. I am trying to code a simple horse race simulation.
I want to know which thread finished first.
This code below throws an error: incompatible types: Thread cannot be converted to Gate
winner = (Gate)Thread.currentThread();
Gate.java
public class Gate implements Runnable{
public String horseName;
public final int GATE_DISTANCE = 20;
public final int FINISH_LINE_DISTANCE = 100;
public CyclicBarrier barrier;
public Gate(CyclicBarrier barrier,String horseName){
this.horseName = horseName;
this.barrier = barrier;
}
public void run(){
//Walk all horses to respective racing gates before starting race
for(int distanceCovered = 0; distanceCovered < GATE_DISTANCE;){
distanceCovered += gallop();
int distanceLeft = GATE_DISTANCE - distanceCovered;
if(distanceLeft < 0){
distanceLeft = 0;
}
System.out.println(horseName + "\t\tgate distance left " + distanceLeft);
if(distanceLeft == 0){
break;
}
}
//Wait for all horses to be at racing gates
try{
barrier.await();
}
catch(InterruptedException ie){
System.out.println("INTERRUPTED");
}
catch(BrokenBarrierException bbe){
System.out.println("BROKEN");
}
//ACTUAL HORSE RACE
for(int distanceCovered = 0; distanceCovered < FINISH_LINE_DISTANCE;){
distanceCovered += gallop();
int distanceLeft = FINISH_LINE_DISTANCE - distanceCovered;
if(distanceLeft < 0){
distanceLeft = 0;
}
System.out.println(horseName + "\t\tgate distance left " + distanceLeft);
if(distanceLeft == 0){
break;
}
}
Main.done();
}
public int gallop(){
final int MIN_GALLOP = 1,
MAX_GALLOP = 10;
Random random = new Random();
int gallopRange = MAX_GALLOP - MIN_GALLOP + 1;
int totalGallop = random.nextInt(gallopRange) + MIN_GALLOP;
return totalGallop;
}
}
GateMain.java
public class GateMain{
private static Gate winner = null;
public static void main(String[] args) {
int horseCount = 5;
List<String> horseNames = new ArrayList<String>();
List<Thread> RG = new ArrayList<Thread>();
horseNames.add("Red Bullet");
horseNames.add("Green Furious");
horseNames.add("Pink Mirage");
horseNames.add("Blue Dash");
horseNames.add("Yellow Burst");
Scanner scan = new Scanner(System.in);
final CyclicBarrier cb = new CyclicBarrier(horseCount,new Runnable(){
public void run(){
System.out.print("\nALL HORSES ARE IN THEIR RESPECTIVE RACING GATES");
System.out.println("\nRACE BEGIN!!!\n");
}
});
for(int horseCtr = 0; horseCtr < horseCount; horseCtr++){
Gate rg = new Gate(cb,horseNames.get(horseCtr));
Thread thread = new Thread(rg);
thread.start();
RG.add(thread);
}
for(Thread thread: RG){
try{
thread.join();
}
catch(InterruptedException ie){
System.out.println("Thread Interrupted");
}
}
System.out.println(winner.horseName + "\t\t\twins!");
}
synchronized static void done(){
if(winner == null){
winner = (Gate)Thread.currentThread();
}
}
}
I would use a global AtomicInteger.
public static AtomicInteger finishLine = new AtomicInteger(0);
Each horse (thread) should have its own place variable,
int place;
and when a horse finishes the race, it sets its own place:
place = finishLine.incrementAndGet();
The first horse to reach the finish line will get place=1, the second horse, place=2, and so on. Then the main() routine must then examine each horse to find out which one has place=1. That'll be the winner.
Here's a different idea, inspired by the finish-line of a cross-country foot race: Instead of an AtomicInteger, use a thread-safe queue.
public static ArrayBlockingQueue<Horse> chute =
new ArrayBlockingQueue<>(NUMBER_OF_HORSES);
When each horse reaches the finish line, it enters the chute.
chute.add(this);
This way, there is no need to explicitly wait for the race to end, and there is no need to explicitly sort the finishers:
Horse win = chute.take(); //waits for the first horse to finish
Horse place = chute.take(); //waits for the second horse
Horse show = chute.take(); //...
However, just synchronizing here will not work, according to the rules of Java. You have to synchronize the update that you want the thread to read, as well. Depending on what variable is, that may or may not be a problem.
You may need to think out your threading model a bit more, and describe here what you want to do. If you were unaware of mutual exclusion, you may not be ready to design threaded code.
if you're trying to access an instance field from a static member, I have to wonder how you got the code to compile.
Thread.currentThread() returns the actual Thread object you (or some other library code) created. That can be a Gate thread, but it all depends on the Thread object it is running in. Safest is to use instanceof to check first.
According to docs Thread.currentThread() returns a reference to the current thread, not the object. So, you should look for reference to the object i.e this keyword.
You wish to have winner as a private member. You can't change it from run() in another class. So, you can pass the current object from run() as an argument to a method in GateMain by this.
You can edit the done() method as:
synchronized static void done(Gate new_gate){
if(winner == null){
winner = new_gate;
}
}
Replace the line Main.done() with Main.done(this)
I'm learning threads so I wanted to make a program which has two types of threads: one that writes random numbers and the other one which checks if the current number matches some specific number. The threads call write() and read(int) methods from the Numbers class. To make things more clear, I want my main program to look like this:
Numbers n = new Numbers();
new WritingThread(n);
new ReadingThread(n,3);
new ReadingThread(n,5);
So the output would be something like this:
2
7
3 !!! MATCH !!!
8
5 !!! MATCH !!!
1
...
The thing is that threads are not executed in order. I want to first execute the WritingThread, and then all the ReadingThreads. Because this way a new random number would be written and only one thread would have the chance to check if the numbers match. Here is the code:
class Numbers:
public class Numbers {
int number;
boolean written = false;
public synchronized void write() {
while (written)
try {
wait();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
number = (int) (Math.random() * 10);
System.out.print("\n" + number);
written = true;
notifyAll();
}
public synchronized void check(int n) {
while (!written)
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.print(" Reading thread: " + Thread.currentThread().getName());
if (n == number)
System.out.print(" !!! MATCH !!! ");
notify();
written = false;
}
}
class WritingThread:
public class WritingThread extends Thread {
Numbers n;
WritingThread(Numbers n){
this.n = n;
start();
}
public void run(){
while(true){
n.write();
}
}
}
class ReadingThread:
public class ReadingThread extends Thread{
Numbers n;
int number;
public ReadingThread(Numbers n, int number){
this.n = n;
this.number = number;
start();
}
public void run(){
while(true){
n.check(number);
}
}
}
And the output:
3 Reading thread: Thread-2
3 Reading thread: Thread-1 !!! MATCH !!!
0 Reading thread: Thread-2
5 Reading thread: Thread-1
0 Reading thread: Thread-2
0 Reading thread: Thread-1
5 Reading thread: Thread-2 !!! MATCH !!!
8 Reading thread: Thread-1
I know i could make one thread which has an array of numbers to check, but I am curious how could it be done this way. Thanks.
Lets start with your example. You have two consumers and one boolean flag. Think through the logic. Let's call our three threads W, C1 and C2.
W post 5
W set flag to true
W send notifyAll
C2 awake
C1 awake
C2 acquire lock
C1 block
C2 no match
C2 notify
W awake
W blocks
C2 release lock
C1 acquire lock
flag is false, C1 waits (releases monitor)
flag is false, C2 waits (releases monitor)
GOTO start
This is just one if the many possible ways in which this code can fun. Any time the lock needs to be acquired there is a free for all and of the threads waiting for it only one can get the lock. That thread will check the value set and reset the flag. If that thread is not the one that the value was intended for it is still consumed.
It should be fairly obvious that you have a race hazard. You are using a single queue for two consumer threads. Each consumer thread is fighting for the queue. Your queue is thread safe in that no more than one thread can read the single item from it at any one time but it causes a race hazard as each consumer thread expects to be the only one reading it. If the wrong thread reads the item then the other thread cannot see it.
The only way to resolve this is to have one queue per thread. The producer puts the same item into each consumer thread's private queue and each consumer thread takes items from its queue and reads them.
Here is an example using an ExecutorSerivce:
public static void main(String[] args) throws Exception {
final class Consumer implements Runnable {
private final BlockingQueue<Integer> q = new LinkedBlockingDeque<>();
private final int search;
public Consumer(final int search) {
this.search = search;
}
#Override
public void run() {
while (true) {
try {
if (q.take() == search) {
System.out.println("Found magic number.");
}
} catch (InterruptedException ex) {
return;
}
}
}
public Queue<Integer> getQ() {
return q;
}
}
final class Producer implements Runnable {
final Random r = new Random();
final Iterable<Queue<Integer>> qs;
public Producer(final Iterable<Queue<Integer>> qs) {
this.qs = qs;
}
#Override
public void run() {
while (true) {
final int i = r.nextInt();
for (final Queue<Integer> q : qs) {
q.offer(i);
}
}
}
}
final int numConsumers = 5;
final Collection<Queue<Integer>> qs = new LinkedList<>();
final ExecutorService es = Executors.newCachedThreadPool();
for (int i = 0; i < numConsumers; ++i) {
final Consumer c = new Consumer(i);
qs.add(c.getQ());
es.submit(c);
}
es.submit(new Producer(qs));
}
You are likely to get very few hits with this example as Random.nextInt() is used. If you want to get more hits reduce the range of the generated random numbers by calling Random.nextInt(int max) which generates numbers [0, max).
As you can see each Consumer has a queue of items to check and it blocks using the BlockingQueue API to wait for new items. The Producer puts the same item into each of the Consumer's queues in turn.
I have an array : int[] arr = {5,4,3,1,2};
I want to do like this::
5 should be read by thread one
4 should be read by thread two
3 should be read by thread one
1 should be read by thread two
2 should be read by thread one
I have tried my best this simple program:
package com.techighost.create.deadlock;
public class ArrayReading implements Runnable {
volatile int index = 0;
int[] arr;
public ArrayReading(int[] arr) {
this.arr = arr;
}
#Override
public void run() {
synchronized (arr) {
for (;index<=(arr.length-1);) {
if (index % 2 == 0 && Thread.currentThread().getName().equals("Thread-One")) {
System.out.println(arr[index] + " " + Thread.currentThread().getName());
index++;
arr.notify();
} else if (index % 2 != 0 && Thread.currentThread().getName().equals("Thread-Two")) {
System.out.println(arr[index] + " " + Thread.currentThread().getName());
index++;
arr.notify();
}else{
System.out.println("In else " + Thread.currentThread().getName());
try {
arr.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public static void main(String[] args) throws InterruptedException {
int[] arr = { 5, 4, 3, 1, 2 };
ArrayReading arrayReading = new ArrayReading(arr);
Thread t = new Thread(arrayReading);
t.setName("Thread-One");
Thread t1 = new Thread(arrayReading);
t1.setName("Thread-Two");
t.start();
t1.start();
t.join();
t1.join();
}
}
I think that this thread name check should not be there? Any body please suggest what can be done to remove this check
You can use condition as mentioned by #zzk.Program
for this can be as
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class PrintSequentially {
private final int[] items;
private final ReentrantLock lock;
private final Condition notEven;
private final Condition notOdd;
private int currentCount = 0;
public PrintSequentially(int[] items) {
this.items = items;
this.lock = new ReentrantLock();
this.notEven = lock.newCondition();
this.notOdd = lock.newCondition();
}
public void printSeq() throws InterruptedException {
try {
lock.lockInterruptibly();
while (currentCount < items.length) {
if (currentCount % 2 == 0) {
System.out.println(Thread.currentThread().getName() + ":"
+ items[currentCount++]);
if (currentCount < items.length)
notEven.await();
notOdd.signal();
} else {
System.out.println(Thread.currentThread().getName() + ":"
+ items[currentCount++]);
notEven.signal();
if (currentCount < items.length)
notOdd.await();
}
}
} finally {
lock.unlock();
}
}
}
Driver program for this is
public static void main(String[] args) {
int arr[] ={1,2,3,4,5};
final PrintSequentially p = new PrintSequentially(arr);
Runnable r1 = new Runnable() {
#Override
public void run() {
try {
p.printSeq();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Runnable r2 = new Runnable() {
#Override
public void run() {
try {
p.printSeq();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Thread th1 = new Thread(r1);
th1.setName("thread 1");
th1.start();
Thread th2 = new Thread(r2);
th2.setName("thread 2");
th2.start();
}
Here you can add as many thread you want. It will print sequentially.
You could use conditions. Thread 1 should wait for condition index % 2 == 0 and Thread 2 should wait for condition index % 2 == 1.
Look at this link for how to use condition
Use another parameter field in your runnable to tell it to read even or odd indices, create two instances of your runnable, one for even, one for odd. Set up an ExecutorService with at least two threads, execute the runnables. It may be possibile they finish too fast to be given different threads. Did not test this.
I understand that this probably is some sort of getting-your-feet-wet thread application but there are a number of problems with it that makes it less than optimal.
The whole point of using threads is asynchronous operation. Wanting your threads to process every other entry in an array sounds like you are dividing up the work but this may run slower than single threaded because of the synchronization to accomplish the every other. The nature of threads also means that "2" may be printed before "1". That's a good thing because you aren't slowing down a thread to get them to be in order.
Your code has some race conditions here. For example, a thread could process the last element of the list and go to wait but the other thread could have already finished the list and won't be there to notify it. I bet your application often hangs at the end.
You should consider using an executor service and submitting a job for each entry. This is the best way to do most threaded task:
// create a thread pool with 2 workers
ExecutorService threadPool = Executors.newFixedThreadPool(2);
for (int entry : arr) {
threadPool.submit(new `(entry));
}
// once we have submitted all jobs to the thread pool, it should be shutdown
threadPool.shutdown();
// to wait for the jobs to finish you do
threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
...
Then your ArrayReading takes the entry not the whole array and can work on them independently.
Lastly, as others have already mentioned, you could pass a boolean even flag to have each thread process even (if true) or odd (if false) items.
Thread t1 = new Thread(new ArrayReading(arr, true));
Thread t2 = new Thread(new ArrayReading(arr, false));
You can use inter thread communication using wait and notify like this :
class ReadNum
{
int arr[];
private volatile int counter = 0;
public ReadNum()
{
counter = 0 ;
}
public ReadNum(int size)
{
arr = new int[size];
for (int i = 0; i < size ; i++)
{
arr[i] = i;
}
}
public void setArray(int[] arr)
{
counter = 0;
this.arr = arr;
}
public synchronized void readOdd()
{
while (counter < arr.length)
{
if (counter % 2 != 0)
{
System.out.println(Thread.currentThread().getName()+":->"+arr[counter]);
counter++;
}
notify();
try{
wait();
}catch(Exception ex){ex.printStackTrace();}
}
notify();//So that other EvenThread does'nt hang if OddThread completes earlier
}
public synchronized void readEven()
{
while (counter < arr.length)
{
if (counter % 2 == 0)
{
System.out.println(Thread.currentThread().getName()+":->"+arr[counter]);
counter++;
}
notify();
try{
wait();
}catch(Exception ex){ex.printStackTrace();}
}
notify();//So that other OddThread does'nt hang if EvenThread completes earlier
}
}
public class SequenceRead
{
public static void main(String st[])
{
final ReadNum rn = new ReadNum();
int arr[]= {1,2,34,78,99,45,4545,987,343,45};
rn.setArray(arr);
Thread th1 = new Thread(new Runnable()
{
#Override
public void run()
{
rn.readEven();
}
},"EvenReadThread");
Thread th2 = new Thread( new Runnable()
{
#Override
public void run()
{
rn.readOdd();
}
},"OddReadThread");
th2.start();th1.start();
}
}
UPDATE
Here is the explanation that you asked for about Race Condition.
Race Condition : "It is a situation where multiple threads can access same resource (typically object's instance variables) and can
produce corrupted data if one thread "races in" or "sneaks in" too
quickly before an operation that should be atomic has completed. Hence the output of program is unpredictable because it is dependent on the sequence or timing of starting, execution and completion of the various threads accessing the same resource ."
For example consider the code given below:
class Race
{
private int counter;
public void printCounter()
{
while(counter < 100)
{
try
{
Thread.sleep(10);//Added to show Race Effect.
}
catch (Exception ex){}
counter = counter + 1;
}
System.out.println(Thread.currentThread().getName() +" : "+counter);//If we don't consider Race condition then the Output should be 100 for all threads.
}
}
public class MainClasss
{
public static void main(String st[])
{
final Race race = new Race();
Thread[] th = new Thread[2];
//Creating 2 threads to call printCounter of object race
for (int i = 0 ; i < th.length ; i++)
{
th[i] = new Thread( new Runnable()
{
public void run()
{
race.printCounter();
}
}, "Thread"+i);
}
//Starting all Threads
for (Thread thr : th )
{
thr.start();
}
}
}
And here is the output that that I am getting , It might vary on your system.
Thread1 : 100
Thread0 : 101
All threads are not printing 100 as expected!!! Why ? Because Program has no control on when an executing Thread will be preempted by another thread.It all depends upon JVM Thread Scheduler.One of the possible explanations for above output is as follows:
At counter = 99 , Thread1 sneaked inside the while loop and slept for 10 ms .
JVM Scheduler now preempted Thread1 by Thread0 .
Thread1 goes inside "while" loop because it finds counter < 100
At Thread.sleep Thread0 is preempted by Thread1.
Thread1 increases the counter by 1.
Thread1 prints the counter value as 100 and finishes.
Thread0 continues execution and increases the counter by 1 and makes counter = 101
Thread0 prints the counter value as 101 and finishes.
This is the live exhibition of Race Condition.
To Avoid this Race condition you should make the ReadNum method as synchronized , So that when a Thread enters that method , it takes the monitor and become owner of the synchronized method . And that thread is preempted only after it completes the all operation Atomically . I hope it gave you a good overview of Race Condition now.
here is the code you are looking for ....
public class ThreadConcurrent {
int []array=new int[]{0,1,2,3,4,5,6,7,8,9};
volatile int i=0;
public void checkSum() {
synchronized (this) {
for(;i<array.length;){
System.out.println("thread name "+Thread.currentThread().getName()+ " : "+array[i]);
i++;
notify();
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
final ThreadConcurrent er=new ThreadConcurrent();
Thread t1=new Thread(new Runnable() {
#Override
public void run() {
er.checkSum();
}
}, "T1");
Thread t21=new Thread(new Runnable() {
#Override
public void run() {
er.checkSum();
}
}, "T2");
t1.start();
t21.start();
}
}