I am trying to simulate a 100 m running race program in java using multithreading. In this attempt I made a Atomic integer variable which should be common to all threads. This variable should increase by 1 after each thread crosses 100. unfortunately the result is not as expected.This is my attempt at the program.
package running;
import java.util.concurrent.atomic.*;
public class Employee implements Runnable{
AtomicInteger j = new AtomicInteger();
public void run() {
for(int i=1;i<=100;i++){
System.out.println(Thread.currentThread().getName()+" " + i);
try {
Thread.sleep(100);
}
catch (InterruptedException e) {
e.printStackTrace();
}
if(i==100)
{
System.out.println(Thread.currentThread().getName()+" is in "+j.incrementAndGet()+" place");
}
}
}
public static void main(String []args) throws Exception{
Employee e= new Employee();
Thread a= new Thread(e,"First");
Thread b= new Thread(e,"Second");
Thread c= new Thread(e,"Third");
Thread d= new Thread(e,"Fourth");
Thread f= new Thread(e,"Fifth");
a.start();
b.start();
c.start();
d.start();
f.start();
}
}
To demonstrate my problem in an understandable way I have added a print statement to check the running of the threads in the code . Here is the last 10 lines of the output.
Second 100
Fourth 100
Third 100
Fifth 100
First 100
Fourth is in 3 place
Third is in 1 place
Second is in 2 place
Fifth is in 4 place
First is in 5 place
I don't see unexpected results. when I run your code I get:
First is in 1 place
Third is in 3 place
Second is in 4 place
Fifth is in 2 place
Fourth is in 5 place
if I run the code again, I get this:
First is in 1 place
Second is in 2 place
Fifth is in 4 place
Fourth is in 3 place
Third is in 5 place
as expected, the results are not always the same. and the AtomicInteger is not losing any update.
if you want the results to be displayed in order, you need to synchronize the part of the code that registers the results. (to make sure that the first thread that reaches 100 will write that information before the next thread reaches 100) for example, see below:
import java.util.ArrayDeque;
import java.util.Queue;
import java.util.concurrent.atomic.AtomicInteger;
public class Employee implements Runnable {
private static AtomicInteger j = new AtomicInteger();
private static Queue<String> queue = new ArrayDeque<>();
public static void main(String[] args) throws Exception {
Employee e = new Employee();
Thread a = new Thread(e, "First");
Thread b = new Thread(e, "Second");
Thread c = new Thread(e, "Third");
Thread d = new Thread(e, "Fourth");
Thread f = new Thread(e, "Fifth");
a.start();
b.start();
c.start();
d.start();
f.start();
a.join();
b.join();
c.join();
d.join();
f.join();
while (queue.size() > 0) {
System.out.println(queue.remove());
}
}
public void run() {
for (int i = 1; i <= 100; i++) {
System.out.println(Thread.currentThread().getName() + " " + i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (queue) {
if (i == 100) {
queue.add(Thread.currentThread().getName() + " is in " + j.incrementAndGet() + " place");
}
}
}
}
}
Related
I am writing a program that uses multithreading to add a array from 1 to 1000, there are 5 threads in total, the result should be different every time, but I get the correct answer every time. How can I make data inconsistency issue? I need to make it result race condition.
public class SyncDemo1 {
public static void main(String[] args) {
new SyncDemo1().startThread(); //need something else beside the correct answer 500500
}
private void startThread() {
int[] num = new int[1000];
ExecutorService executor = Executors.newFixedThreadPool(5);
MyThread thread1 = new MyThread(num, 1, 200);
MyThread thread2 = new MyThread(num, 201, 400);
MyThread thread3 = new MyThread(num, 401, 600);
MyThread thread4 = new MyThread(num, 601, 800);
MyThread thread5 = new MyThread(num, 801, 1000);
executor.execute(thread1);
executor.execute(thread2);
executor.execute(thread3);
executor.execute(thread4);
executor.execute(thread5);
executor.shutdown();
while (!executor.isTerminated()) {
}
int temp = thread1.getSum() + thread2.getSum() + thread3.getSum() + thread4.getSum()+ thread5.getSum();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
int totalSum = temp;
System.out.println(totalSum);
}
private static void pause() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
private static class MyThread implements Runnable {
private int[] num;
private int from , to , sum;
public MyThread(int[] num, int from, int to) {
this.num = num;
this.from = from;
this.to = to;
sum = 0;
}
public void run() {
for (int i = from; i <= to; i++) {
sum += i;
}
pause();
}
public int getSum() {
return this.sum;
}
}
}
If you need to experiment with race conditions, you can experiment using this demo class
class RaceConditionDemo implements Runnable {
private int counter = 0;
public void increment () {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
counter++;
}
public void decrement () {
counter--;
}
public int getValue () {
return counter;
}
#Override
public void run () {
this.increment();
System.out.println("Value for Thread After increment "
+ Thread.currentThread().getName() + " " + this.getValue());
this.decrement();
System.out.println("Value for Thread at last "
+ Thread.currentThread().getName() + " " + this.getValue());
}
public static void main (String args[]) {
RaceConditionDemo counter = new RaceConditionDemo();
Thread t1 = new Thread(counter, "Thread-1");
Thread t2 = new Thread(counter, "Thread-2");
Thread t3 = new Thread(counter, "Thread-3");
Thread t4 = new Thread(counter, "Thread-4");
Thread t5 = new Thread(counter, "Thread-5");
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
}
}
Here, the Runnable class contains a primitive int as a shared resource. As you may know, primitives are not thread-safe and pre-increment nor post-increment are atomic operations. Run enough times, and you will notice the values printed out are not predictable.
I feel weird posting this as an answer because your question seeks code that is implemented incorrectly. This is a first for me.
The output (of one of the runs)
Value for Thread After increment Thread-3 5
Value for Thread After increment Thread-5 5
Value for Thread After increment Thread-1 5
Value for Thread After increment Thread-2 5
Value for Thread at last Thread-2 1
Value for Thread After increment Thread-4 5
Value for Thread at last Thread-1 2
Value for Thread at last Thread-5 3
Value for Thread at last Thread-3 4
Value for Thread at last Thread-4 0
Notice how, sometimes, one thread executes it's run() method while another thread is still in the middle of the execution. So you may see "Value for Thread After increment" printed out consecutively before either one got a chance to execute the decrement and print out "Value for Thread at last". This causes an instability in the value being printed out. In fact, it is possible that the value of the counter variable changes just before one thread finishes the increment or decrement.
I have a simple concurrent code that increments a shared variable.
Two threads increment the counter 10,000,000 times each and print the result.
It works alright (race condition is resolved with synchronized inside the increment method).
However after thread A is done incrementing, thread B starts incrementing before thread A has a chance to prints its result (should be 10,000,000). I can resolve it by getting thread B to sleep 3 seconds before starting its own increment:
public class DogLatch {
private static Counter counter = new Counter();
public static void main(String[] args) throws Exception {
Thread a = new Thread(new A());
Thread b = new Thread(new B());
a.start();
b.start();
a.join();
b.join();
System.out.printf("counter: %,d", counter.getValue());
}
static class Counter {
private int i;
public void increment() {
synchronized (this) {
i++;
}
}
public int getValue() {return i;}
public void setValue(int i ) {this.i = i;}
}
static class A implements Runnable {
#Override
public void run() {
for (int i = 0; i < 10_000_000; i++) {
counter.increment();
}
System.out.println("A done: " + counter.getValue());
}
}
static class B implements Runnable {
#Override
public void run() {
System.out.println("Go to school");
System.out.println("Walk dog");
try {
Thread.sleep(5000);
}
catch (Exception e) {
e.printStackTrace();
}
for (int i = 0; i < 10_000_000; i++) {
counter.increment();
}
System.out.println("B done: " + counter.getValue());
}
}
}
would print
Go to school
Walk dog
A done: 10000000
B done: 20000000
counter: 20,000,000
However if I repalce B with:
static class B implements Runnable {
#Override
public void run() {
System.out.println("Go to school");
System.out.println("Walk dog");
for (int i = 0; i < 10_000_000; i++) {
counter.increment();
}
System.out.println("B done: " + counter.getValue());
}
}
I get
Go to school
Walk dog
A done: 17368068
B done: 20000000
counter: 20,000,000
output. Is there a way to achieve the correct output where A done: 10000000 and B done: 10000000 is displayed, without resorting to Thread.sleep() in B?
Actually, your program is not really doing much concurrent processing. You wait 5 seconds in thread B while thread A increments up to 10,000,000 and then B wakes up and continues.
This would be the result if you just started them one after the other in a single thread.
But you know it's working fine since the the end result is always 20,000,000 without the sleep statement.
If you force alternation you will loose the benefit of using threads. The fact that A prints out different values but the final tally is 20,000,000 is indicative of it working perfectly!
In the code, the thread output is not properly synchronized. The output should be the numbers in increasing order.
here is the code
public class Prog {
public static void main(String[] args) {
Thread a = new Thread(new Writer(), "A");
Thread b = new Thread(new Writer(), "B");
Thread c = new Thread(new Writer(), "C");
a.start();
b.start();
c.start();
}
static class Writer implements Runnable {
private static int count;
#Override
public void run() {
while (count < 5) {
show();
}
try {
Thread.sleep(200);
} catch (InterruptedException ex) {
}
}
private synchronized void show() {
System.out.println(Thread.currentThread().getName() + ":\t" + ++count);
}
}
}
One output of this code is:
B: 2
B: 4
C: 3
A: 2
B: 5
whereas expected output is:
B: 1
B: 2
C: 3
A: 4
B: 5
What am I missing? Please help.
Each Writer synchronizes (implicitly) on itself - so you have three writers and three separate locks (no real synchronization between them can occur).
If you change the show method to static, the writers will synchronize on the Writer class instead - this way all the writers will share the lock and be synchronized with each other.
I am trying to print these threads 1 character per second with no order. If I put in sleep then it becomes in order. How do I make it not in order and print 1 character (any) per second.
public class Number1{
public static void main(String[] args){
try{
Thread a = new Thread(new thread1("A"));
Thread b = new Thread(new thread1("B"));
Thread c = new Thread(new thread1("C"));
a.start();
b.start();
c.start();
a.join(1000);
b.join(1000);
c.join(1000);
}
catch(InterruptedException e) {
System.out.println("Error");
}
}
}
class thread1 implements Runnable{
String character;
public thread1(String a){
this.character = a;
}
public void run(){
for(int i = 1;i<21;i++)
{
System.out.println("No."+i+" Thread: "+character);
}
}
}
Thread.sleep() is a method which will make your thread to sleep for 1 second and continue. You are using the method join. So change it to thread.sleep(1000
public class Number1{
public static void main(String[] args){
try{
Thread a = new Thread(new thread1("A"));
Thread b = new Thread(new thread1("B"));
Thread c = new Thread(new thread1("C"));
a.start();
b.start();
c.start();
a.join(1000);
b.join(1000);
c.join(1000);
}
catch(InterruptedException e) {
System.out.println("Error");
}
}
}
class thread1 implements Runnable{
String character;
public thread1(String a){
this.character = a;
}
public void run(){
for(int i = 1;i<21;i++)
{
Thread.sleep(1000);// This will make the current thread sleep for 1 second
System.out.println("No."+i+" Thread: "+character);
}
}
}
I added a sleep to the for loop in your code and it seems to be working.
No.1 Thread: C
No.1 Thread: B
No.1 Thread: A
No.2 Thread: A
No.2 Thread: C No.2 Thread: B No.3 Thread: A No.3 Thread: C No.3 Thread: B
No.4 Thread: C No.4 Thread: B No.4 Thread: A No.5 Thread: A No.5
Thread: BNo.5 Thread: C
The characters A,B,C are displayed in a random order. Is this not what you're trying to achieve?
I would use a semaphore.
I'd initialize the semaphore to have zero permits, and I'd make each of the three counting threads take one permit each time around the loop. Finally, I'd have the main thread loop, adding one permit to the semaphore ever second until all of the threads have finished.
If I understand correctly you are trying to create what's called a race condition: The character that gets printed depends on the thread that gets there first. Now, because of this it is normal that three characters get printed simultaneously instead of one at a time. If it didn't, the order wouldn't be random anymore. What may work best is having the three threads shuffle up the order first by remembering the order in which each of them wants to print a character, then join the threads again and then print out the three characters from one of the threads. I'm by no means an expert on this but I think you need to put the code that appends the character to the string in a synchronised block, as well. A bit like this:
public class Number1
{
public static void main(String[] args)
{
Printer printer=new Printer();
try
{
Thread a = new Thread(new thread1("A", printer));
Thread b = new Thread(new thread1("B", printer));
Thread c = new Thread(new thread1("C", printer));
a.start();
b.start();
c.start();
a.join(1000);
b.join(1000);
c.join(1000);
}
catch(InterruptedException e)
{
System.out.println("Error");
}
}
}
class Printer
{
int i=0;
String[] strings=new String[3];
//this method only prints and waits if it is called by the last of the three threads, to print all three
//characters. So it returns true if the thread itself needs to wait three seconds. All three
//threads must try to call it simultaneously so the order is random; to prevent errors though the method is synchronised.
public synchronized boolean print(String s)
{
strings[i++]=s;
if(i==3)
{
for(i=0; i<3; i++)
{
System.out.println(strings[i]);
try
{
Thread.sleep(1000);
}
catch(Exception e)
{
}
}
i=0;
return false;
}
return true;
}
}
class thread1 implements Runnable
{
String character;
Printer printer;
public thread1(String a, Printer printer)
{
this.character = a;
this.printer=printer;
}
public void run()
{
for(int i = 1;i<21;i++)
{
if(printer.print("No."+i+" Thread: "+character))
{
try
{
Thread.sleep(3000);
}
catch(Exception e)
{
}
}
}
}
}
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();
}
}