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)
Related
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 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.
I hope this is not a repeat question, but I have looked at all the answers in other questions and none have satisfied my problem.
I have a program that has solves the Dining Philosopher's problem, and when I run the program, the threads wait until the next one is done before running another. This causes the thread's output to look like:
Philosopher 1 is EATING.
Philosopher 1 is THINKING.
Philosopher 5 is EATING.
Philosopher 5 is THINKING.
Philosopher 3 is EATING.
Philosopher 3 is THINKING.
... and so on. The expected output doesn't have an order. The threads should run concurrently. Here is my code, all of it is in here, with the interface just specifying the size of DINERS (5) and the State._______ is an enumeration with 3 states: State.HUNGRY, State.THINKING, and State.EATING.
import java.lang.Runnable;
import java.util.concurrent.locks.*;
import java.util.Random;
import java.lang.Thread;
import java.util.concurrent.TimeUnit;
/**
* This class handles the Philosophers, I hope they are hungry.
*
* #version 4-20-15
*/
public class Diner implements Runnable, PhilosopherInterface {
/** The lock used to control Thread access */
private final ReentrantLock lock;
/** The state that the Philosopher is in (ex: Eating, Thinking etc.) */
private State current;
/** The random number used to generate time sleeping */
private Random timeGenerator;
/** The maximum time a thread can sleep */
private final int maxTimeToSleep = 5000;
/** The minimum time a thread can sleep (1ms) */
private final int minTimeToSleep = 1;
private int philNum;
private int philIndex;
private Condition[] condition;
private State[] states;
public Diner(ReentrantLock lock, int philNumber, Condition[] condition, State[] states)
philNum = philNumber;
philIndex = philNum - 1;
current = states[philNumber-1];
timeGenerator = new Random();
this.lock = lock;
this.condition = condition;
this.condition[philIndex] = lock.newCondition();
this.states = states;
states[philIndex] = State.THINKING;
}
#Override
public void takeChopsticks() {
states[philIndex] = State.HUNGRY;
lock.lock();
try{
int left = philIndex-1;
int right = philIndex+1;
if(philNum == DINERS) right = 0;
if(philNum == 1) left = DINERS - 1;
test(left, philIndex, right);
if(states[philIndex] != State.EATING) {
condition[philIndex].await();
}
}catch(InterruptedException e){}
}
#Override
public void replaceChopsticks() {
try{
states[philIndex] = State.THINKING;
int left = philIndex-1;
int right = philIndex+1;
if(philNum == DINERS) right = 0;
if(philNum == 1) left = DINERS - 1;
int leftOfLeft = left-1;
int rightOfRight = right+1;
if(left == 0) leftOfLeft = DINERS-1;
test(leftOfLeft, left, philIndex);
if(right == DINERS-1) rightOfRight = 0;
test(philIndex, right, rightOfRight);
}finally{ lock.unlock(); }
//states[philIndex] = State.THINKING;
//condition[left].signal();
//condition[right].signal();
}
public void think() {
System.out.println("Philosopher " + philNum + " is " + State.THINKING + ".");
int timeToSleep = timeGenerator.nextInt(maxTimeToSleep) + minTimeToSleep;
try {
Thread.sleep(500);
}catch(InterruptedException e) {}
}
public void eat() {
System.out.println("Philosopher " + philNum + " is " + State.EATING + ".");
int timeToSleep = timeGenerator.nextInt(maxTimeToSleep) + minTimeToSleep;
try {
Thread.sleep(500);
}catch(InterruptedException e){}
}
#Override
public void run() {
while(true) {
think();
takeChopsticks();
eat();
replaceChopsticks();
}
}
public State getState() {
return current;
}
private void test(int left, int current, int right) {
if(states[left] != State.EATING && states[current] == State.HUNGRY
&& states[right] != State.EATING) {
states[current] = State.EATING;
condition[current].signal();
}
}
}
Why are the treads not running concurrently? Thanks for the help!
EDIT: To run it, there is a driver that is this:
public class Lunch {
public static void main(String[] args) {
ReentrantLock lock = new ReentrantLock();
Thread[] diners = new Thread[PhilosopherInterface.DINERS];
Condition[] table = new Condition[PhilosopherInterface.DINERS];
State[] states = new State[PhilosopherInterface.DINERS];
for(int i=0; i<PhilosopherInterface.DINERS; i++) {
states[i] = State.THINKING;
}
for(int i=0; i<PhilosopherInterface.DINERS; i++) {
Diner diner = new Diner(lock, i+1, table, states);
diners[i] = new Thread(diner);
diners[i].start();
}
}
}
EDIT2: Figured out the problem, Answer below.
Telling your threads to wait is not forcing them to work concurrently. If a thread needs to follow several steps before another one activates, then these methods(steps) should be synchronized.
I only locked once at the beginning of takeChopsticks() and unlocked at the end of replaceChopsticks(), forcing the thread to do everything before unlocking.
I used the lock() and unlock() methods at the start and finish of both takeChopsticks() and replaceChopsticks(), allowing it to run concurrently.
Try using an ExecutorService. Use ExecutorService.submit(Runnable)
and ExecutorService.shutdown() which will wait until all the Runnables have terminated and shutdown the ExecutorService.
This is the code I am running:
public class MyRunnableClass implements Runnable {
static int x = 30;
int y = 0;
#Override
public void run() {
for(int i=0;i<30;i++){
getFromStash();
}
}
public synchronized void getFromStash(){
x--;
y++;
}
}
and my Test class:
public class MyRunnableClassTest {
public static void main(String[] args){
MyRunnableClass aa = new MyRunnableClass();
MyRunnableClass bb = new MyRunnableClass();
Thread a = new Thread(aa);
Thread b = new Thread(bb);
a.start();
b.start();
System.out.println(aa.y);
System.out.println(bb.y);
}
}
Sometimes I see output:
30
30
and sometimes I see:
30
0
Why? The method I have, is synchronized?
I actually expect to see something like 15 - 15 but it is definetly not what I am getting.
You need to wait for the threads to finish.
a.start();
b.start();
a.join();
b.join();
System.out.println(aa.y);
System.out.println(bb.y);
At that point you should see predictable results.
Added
Now you've had a chance to play - here's my attempt at what you seem to be trying to do.
public class MyRunnableClass implements Runnable {
static AtomicInteger stash = new AtomicInteger(1000);
int y = 0;
#Override
public void run() {
try {
while (getFromStash()) {
// Sleep a little 'cause I'm on a single-core machine.
Thread.sleep(0);
// Count how much of the stash I got.
y += 1;
}
} catch (InterruptedException ex) {
System.out.println("Interrupted!");
}
}
public boolean getFromStash() {
// It must be > 0
int was = stash.get();
while (was > 0) {
// Step down one.
if (stash.compareAndSet(was, was - 1)) {
// We stepped it down.
return true;
}
// Get again - we crossed with another thred.
was = stash.get();
}
// Must be 0.
return false;
}
}
Remove the bb and use only the aa object to create the two threads.
It's synchronized on this and you use two different objects (i.e. this values) - aa and bb. So practically you defeat the whole synchronization idea by using the two different objects.
Thread a = new Thread(aa);
Thread b = new Thread(aa);
a.start();
b.start();
Alternatively, you can do something like this.
public class MyRunnableClass implements Runnable {
private static final Object lock = new Object();
static int x = 30;
int y = 0;
#Override
public void run() {
for(int i=0;i<30;i++){
getFromStash();
}
}
public void getFromStash(){
synchronized(lock){
x--;
y++;
}
}
}
Here is what I think you want to achieve.
class Stash {
private int x = 30;
private int y = 0;
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public synchronized void getFromStash(){
System.out.println("Method getFromStash called by " + Thread.currentThread().getName() + ".");
x--;
y++;
}
}
public class MyRunnableClass implements Runnable {
private Stash st = null;
private volatile boolean done = false;
public MyRunnableClass(Stash st){
this.st = st;
}
#Override
public void run() {
for(int i=0;i<30;i++){
this.st.getFromStash();
try {
double m = Math.random();
Thread.sleep((long)((m + 1) * 100.0));
}catch(InterruptedException ex){
ex.printStackTrace();
}
}
System.out.println("Thread ---> " + Thread.currentThread().getName() + " finished!");
this.done = true;
}
public static void main(String[] args) throws Exception {
Stash st = new Stash();
MyRunnableClass aa = new MyRunnableClass(st);
MyRunnableClass bb = new MyRunnableClass(st);
Thread a = new Thread(aa);
Thread b = new Thread(bb);
a.setName("Thread A");
b.setName("Thread B");
a.start();
b.start();
while (true){
System.out.println(st.getX() + " " + st.getY());
Thread.sleep(10);
if (aa.done && bb.done) break;
}
System.out.println("Main thread finished too!");
}
}
Since you print the values right after you start the threads, you're not going to "catch" the threads in the middle of the for loops. The thread scheduler is returning control to the main thread sometimes after the threads are done and sometimes before they start, but never during run(). You have to wait until the threads are done.
As you've already figured out, your first attempt didn't work the way you wanted because 1) you weren't waiting for the threads to finish, so sometimes you read the values before they'd done their work, and 2) you're not looking for each thread to pull from the stash 30 times, but rather for the sum total of the pulls to be 30 (divided among the threads however it happens).
Your move to stopping each thread when x > 0 instead of after N pulls is the right approach, but the test for whether x > 0 (and therefore whether to continue) needs to be synchronized as well. Otherwise you could test the value and find that x == 1, decide to do a pull, and then before you actually do it the other thread takes the last one. Then you do your pull, leaving x at -1 and the sum of the two y's at 31.
To solve this, you either need to put a check for x > 0 within the synchronized getFromStash() method (so you don't actually change x and y unless it's safe to do so), or you need to expose the lock outside the Stash object from peter.petrov's answer, so that both threads can explictly synchronize on that object when they test x > 0 and then call getFromStash() if applicable.
Also, it's generally much harder to figure out thread synchronization when you're using static variables; there tend to be interactions you don't anticipate. You're much better off creating a separate object (e.g. peter.petrov's Stash class) to help you represent the pool, and the pass a reference to it to each of your thread classes. That way all access is via non-static references, and you'll have an easier time making sure you get the code right.
I have a class here that will be used as a thread/Runnable object, the second class below (UseSearch) has a main method that intantiates two instances of the Search class and uses them to create two threads. As you can see, the run method calls the add method that runs the loop depending on the direction passed in. I am looking for a mechanism that will cause one of the threads to stop the other thread's loop from iterating when the other thread has finished running it's iteration. Any help/advise will be highly appreciated. I have seen a similar example but it's far too complex for me to comprehend. - Jevison7x
public class Search implements Runnable
{
int sum;
boolean direction;
String name;
public Search(String n, boolean positive)
{
this.direction = positive;
this.name = n;
}
void add()
{
if(direction == true)
{
for(int i = 0; i < 100; i++)
{
sum += 1;
System.out.println(name+" has "+sum);
}
}
else
{
for(int i = 0; i < 100; i++)
{
sum -= 1;
System.out.println(name+" has "+sum);
}
}
}
public void run()
{
add();
}
}
public class UseSearch
{
public static void main(String[] args)
{
Search s1 = new Search("bob", true);
Search s2 = new Search("dan", false);
Thread t1 = new Thread(s1);
Thread t2 = new Thread(s2);
t1.start();
t2.start();
}
}
The thread that is doing the iterating needs to test something on each iteration to see if it has been told to stop. That could be a custom flag (implemented in a variety of ways) or a the thread's interrupted flag.
If you are going to use interrupt, then Matt Clark's answer is half of the picture. The other half is that the iterating thread needs to do something like this:
if (Thread.currentThread.isInterrupted()) {
// pause or stop or break out of the loop or whatever
}
... in the body of the relevant loop or loops.
Note: there is no safe way in Java to stop or pause another thread that is not regularly checking to see if it should stop / pause; i.e. a thread that is not cooperating.
Long answer short...
Make the Threads class-wide variables so that each thread has access to the other:
Thread t1, t2;
public static void main(String[] args){
t1 = new Thread(){
public void run(){
t2.interrupt();
}
};
t2=new Thread(){
public void run(){
t1.interrupt();
}
};
}