How can i get class variable in run method thread (Java) - java

My problem concern thread. i want to get var(class variable) from method run but can't get and
i don't know what happed.
import java.util.ArrayList;
public class Interpreter_controller extends Thread{
ArrayList<String> var;
public Interpreter_controller(ArrayList<String> var) {
this.var = var;
System.out.println(this.var.isEmpty());
}
public void run() {
System.out.println(this.var.isEmpty());
}
}
when i start thread from
Interpreter_controller control = new Interpreter_controller(array_list_variable);
control.start();
Output is
false
true
What should I do to get var from run method?
New Edit
I delete extends Thread then result is correct but i want to use thread in this class
My goal is pass arraylist from another class to use in thread class(run method)

Hi Following will give you head start. Make sure list is synchronized.
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
public class Main {
public static void main(String[] args) throws InterruptedException {
Main m = new Main();
m.execute();
}
public void execute() throws InterruptedException {
List<String> list = new ArrayList<String>();
list = Collections.synchronizedList(list);
List<Thread> tlist = new ArrayList<Thread>();
for (int i = 0; i < 5; i++) {
Thread t = new SomeThread(list, i);
t.start();
tlist.add(t);
}
while (true) {
int j = 0;
for (int i = 0; i < tlist.size(); i++) {
Thread.sleep(100);
if (!tlist.get(i).isAlive()) {
j++;
for (String s : list) {
System.out.println(s);
}
}
}
if (j == tlist.size()) {
break;
}
}
}
public class SomeThread extends Thread {
private List<String> list;
private int number;
private long sleepTime;
public SomeThread(List list, int number) {
this.list = list;
this.number = number;
sleepTime = new Random(number).nextInt(500);
}
#Override
public void run() {
try {
Thread.sleep(sleepTime);
list.add(number + " wake up from sleep");
} catch (InterruptedException e) {
System.out.println(e);
}
}
}
}

My goal is pass arraylist from another class to use in thread
class(run method)
Take a look at this:
class Tmp implements Runnable {
public Object runArg;
public Tmp(Object arg) {
runArg = arg;
}
public void run() {
// thread job
}
}
Use:
new Thread(new Tmp("Hello World")).start();
So you have to create a new class rather than using anonymous class.
NOTE: Unless you are using J2ME, you should NOT use native Thread. Many problems would occur with you. You should use ExecutorService by using Executors classes:
private final ExecutorService pool = Executors.newCashedThreadPool();
...
pool.submit(new Tmp("HelloWorld"));

Related

Explain about the volatile in this case in java

I have a following code as below:
class Example {
private volatile int testValue = 0;
public int getTestValue() {
return testValue;
}
public void setTestValue(int testValue) {
this.testValue = testValue;
}
public void increment() {
this.testValue += 1;
}
}
class PrintThread extends Thread {
private Example example;
private int x = 0;
public PrintThread(Example example) {
this.example = example;
x = example.getTestValue();
}
public void run() {
while(true) {
if(x != example.getTestValue()) { // block 1
System.out.println("printThread: " + example.getTestValue());
x = example.getTestValue();
}
}
}
}
class IncrementorThread extends Thread {
private Example example;
public IncrementorThread(Example example) {
this.example = example;
}
public void run() {
while(true) {
example.increment();
System.out.println("incrementorThread: " + example.getTestValue());
try {
Thread.sleep(800);
} catch(Exception ex) {
}
}
}
}
public class VolatileExample {
public static void main(String args[]) {
Example ex = new Example();
new IncrementorThread(ex).start();
new PrintThread(ex).start();
}
}
When I remove volatile keyword in Example class then I never see the output of PrintThread. In PrintThread when I print out the testValue of example, value of example object still updated but the code in 'block 1' never be executed. Both thread still access the same object, can anyone explain me more detail about this? About the volatile keyword affected in this case
You should use atomic integers insteed of volatile fields. To get the idea why that is important try running code below. Here you have 3 types of variables, normal int, volatile int and AtomicInteger. Only AtomicInteger assure the thread safety of value. After running this simple code, you will see why.
public class Test {
private int threadCount = 10;
private int nonVolatileCount = 0;
private volatile int volatileCount = 0;
private AtomicInteger atomicCount = new AtomicInteger(0);
private CountDownLatch startLatch = new CountDownLatch(threadCount);
private CountDownLatch endLatch = new CountDownLatch(threadCount);
private class Task implements Runnable {
public void run() {
startLatch.countDown();
try {
startLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 0; i < 1000000; i++) {
nonVolatileCount++;
volatileCount++;
atomicCount.incrementAndGet();
}
endLatch.countDown();
};
}
public static void main(String[] args) throws InterruptedException {
new Test().go();
}
public void go() throws InterruptedException {
for (int i = 0; i < threadCount; i++) {
new Thread(new Task()).start();
}
endLatch.await();
System.out.println("non volatile counter: " + nonVolatileCount);
System.out.println(" volatile counter: " + volatileCount);
System.out.println(" atomic counter: " + atomicCount.get());
}
}

Use Java concurrency to run a multi-threaded task until there is enough output

I have a task in Java that is currently single threaded and may or may not produce output. I need to run this task until I have 100 pieces of output from it. Here is the single threaded (greatly simplified) example version of this:
import java.security.SecureRandom;
public class Test {
private static SecureRandom rand = new SecureRandom();
public static String task() {
return rand.nextDouble() > 0.5 ? "output" : null;
}
public static void main(String[] args) {
int outputCount = 0;
while (outputCount < 100) {
String output = task();
if (output != null) {
outputCount++;
System.out.println(output);
}
}
}
}
I would like to run this task multi-threaded in four (4) threads. How do I implement it?
I've looked into using the Executor interfaces but they appear to be geared at running a task exactly n times, not until needed.
Some additional notes:
I don't care if I get 103 pieces of output and have to discard 3 of them
One object that the task uses is expensive to construct, is not thread safe, but could be used again by a task that runs later. (This is represented by the SecureRandom in the above example.) Ideally, I'd like a thread pool that lets me instantiate exactly four of these objects.
I think in your case you can use just an AtomicInteger that is shared between your tasks.
public class MyTask
implements Runnable
{
private AtomicInteger counter;
public MyTask ( AtomicInteger counter )
{
this.counter = counter;
}
public void run ()
{
while ( true )
{
String output = task();
if ( output != null )
{
int count = counter.getAndIncrement( );
System.out.println(output);
if ( count >= 100 )
{
break;
}
}
}
}
public static String task() {
return rand.nextDouble() > 0.5 ? "output" : null;
}
public static void main (
String[] args
) throws InterruptedException
{
AtomicInteger counter = new AtomicInteger( );
ExecutorService pool = Executors.newFixedThreadPool(4);
for (int i = 0; i < 4; ++i)
{
pool.execute( new MyTask( counter ) );
}
// Simplified shutdown, do not use this in production
pool.shutdown( );
pool.awaitTermination(1, TimeUnit.HOURS);
}
}
You could still use an Executor service but use some longer-living Runnables to run the execution and pull the reusable objects from some shared map of objects. Here is a quick example with comments that I think could work for you. EDIT: I updated my previous example to meet the requirement of at least 100 pieces of output, but possibly more:
import java.security.SecureRandom;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class Example {
private static AtomicInteger outputCount = new AtomicInteger(0);
private static SecureRandom rand = new SecureRandom();
public static void main(String[] args) throws InterruptedException {
BlockingQueue<Object> expensiveObjects = new LinkedBlockingQueue<>();
// Random objects put in
expensiveObjects.put(new Object());
expensiveObjects.put(new Object());
expensiveObjects.put(new Object());
expensiveObjects.put(new Object());
ExecutorService executorService = Executors.newFixedThreadPool(4);
for (int i = 0 ; i < 4; i++) {
executorService.execute(new MyRunnable(expensiveObjects));
}
// Arbitrary wait in this example.
executorService.shutdown();
executorService.awaitTermination(5, TimeUnit.SECONDS);
System.out.println("Final: " + outputCount.get());
}
public static String task() {
return rand.nextDouble() > 0.5 ? "output" : null;
}
/**
* Runnable that keeps executing while outputCount is less than 100.
*/
private static class MyRunnable implements Runnable {
private final BlockingQueue<Object> expensiveObjects;
public MyRunnable(final BlockingQueue<Object> expensiveObjects) {
this.expensiveObjects = expensiveObjects;
}
#Override
public void run() {
while (true) {
try {
Object expensiveObject = expensiveObjects.take();
// Use the expensive object that you talked about and put it back for reuse when done. Not needed in this example but leaving it for now
String output = task();
expensiveObjects.put(expensiveObject);
if (output != null) {
int counter = outputCount.getAndIncrement();
System.out.println(counter);
if (counter >= 100) {
break;
}
}
} catch (InterruptedException e) {
System.out.println("Error!");
}
}
}
}
}
I suggest using a CountDownLatch for limiting the number of output objects to 100
For delivering the ouput in a thread safe way you could just use a ArrayList which you have decorated with Collections.synchronizedList to make it thread safe
For accessing the not thread safe operation you could make it thread safe by synchronizing on the expensive object which produces the output object
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class CountDownTask implements Runnable{
private final CountDownLatch latch;
private final List<String> output;
private final SecureRandom random;
public CountDownTask( CountDownLatch latch, List<String> output, SecureRandom random ) {
super();
this.latch = latch;
this.output = output;
this.random = random;
}
public void run() {
while(latch.getCount() > 0){
if(getNextValueInAThreadSafeWay() > 0.5){
output.add("output");
latch.countDown();
}
}
}
private double getNextValueInAThreadSafeWay(){
synchronized(random){
return random.nextDouble();
}
}
public static void main(String[] args) throws InterruptedException{
CountDownLatch theLatch = new CountDownLatch( 100 );
List<String> output = Collections.synchronizedList( new ArrayList<String>() );
SecureRandom random = new SecureRandom();
ExecutorService service = Executors.newCachedThreadPool();
for(int i=0;i<4;i++){
service.execute( new CountDownTask( theLatch, output, random ) );
}
theLatch.await( 1, TimeUnit.MINUTES );
service.shutdown();
System.out.println(output.size());
}
}
The simplest approach:
Use AtomicInteger to make the count thread safe (as suggested by Alexander Pogrebnyak's answer)
Use an ExecutorService which can invokeAll a list of Callable and wait until they all finish.
Put SecureRand rand and String task() as member elements of the Callable
Move the loop inside the Callable's call() method, have each thread complete tasks until there are no more tasks to complete.
Here is the implementation:
import java.security.SecureRandom;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
public class Test {
private static final int TASKS = 100;
private static final int THREADS = 4;
public static void main(String[] args) throws InterruptedException {
final AtomicInteger outputCount = new AtomicInteger(0);
ExecutorService threadPool = Executors.newFixedThreadPool(THREADS);
Collection<Callable<Object>> tasks = new ArrayList<>(THREADS);
for (int i = 0; i < THREADS; i++) {
tasks.add(new Callable<Object>() {
private SecureRandom rand = new SecureRandom();
private String task() {
return rand.nextDouble() > 0.5 ? Thread.currentThread().getName() : null;
}
#Override public Object call() {
for (int i; (i = outputCount.get()) < TASKS;) {
String output = task();
if (output != null) {
if ((i = outputCount.incrementAndGet()) < TASKS) {
System.out.println(output + ": " + i);
}
}
} return null;
}
});
}
threadPool.invokeAll(tasks);
threadPool.shutdownNow();
System.out.println("done");
}
}
Well, here's my shot at it. Worked for me:
public class MakeItConcurrent {
private static final ExecutorService threadPool = Executors.newFixedThreadPool(4);
private static final AtomicInteger outputCount = new AtomicInteger();
private static final ThreadLocal<SecureRandom> threadToStringBuilder = new ThreadLocal<SecureRandom>();
public static String task() {
SecureRandom rand = threadToStringBuilder.get();
if (rand == null) {
threadToStringBuilder.set(new SecureRandom());
rand = threadToStringBuilder.get();
}
return rand.nextDouble() > 0.5 ? "output" : null;
}
public static void doManyTasks() {
int currOutputCount;
while ( ( currOutputCount = outputCount.get() ) < 100) {
String output = task();
if (output != null) {
// outputCount.compareAndSet(currOutputCount, currOutputCount + 1); use this if you want exactly 100 outputs
outputCount.set(currOutputCount + 1);
System.out.println(output);
}
}
threadPool.shutdownNow();
}
public static void main(String[] args) throws InterruptedException {
Runnable runnable = new Runnable() {
#Override public void run() {
doManyTasks();
}
};
threadPool.submit(runnable);
threadPool.submit(runnable);
threadPool.submit(runnable);
threadPool.submit(runnable);
while ( ! threadPool.isShutdown() ) {
Thread.sleep(100);
}
System.out.println(outputCount);
}
}

Ordering threads to run in the order they were created/started

How can i order threads in the order they were instantiated.e.g. how can i make the below program print the numbers 1...10 in order.
public class ThreadOrdering {
public static void main(String[] args) {
class MyRunnable implements Runnable{
private final int threadnumber;
MyRunnable(int threadnumber){
this.threadnumber = threadnumber;
}
public void run() {
System.out.println(threadnumber);
}
}
for(int i=1; i<=10; i++){
new Thread(new MyRunnable(i)).start();
}
}
}
Sounds like you want ExecutorService.invokeAll, which will return results from worker threads in a fixed order, even though they may be scheduled in arbitrary order:
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class ThreadOrdering {
static int NUM_THREADS = 10;
public static void main(String[] args) {
ExecutorService exec = Executors.newFixedThreadPool(NUM_THREADS);
class MyCallable implements Callable<Integer> {
private final int threadnumber;
MyCallable(int threadnumber){
this.threadnumber = threadnumber;
}
public Integer call() {
System.out.println("Running thread #" + threadnumber);
return threadnumber;
}
}
List<Callable<Integer>> callables =
new ArrayList<Callable<Integer>>();
for(int i=1; i<=NUM_THREADS; i++) {
callables.add(new MyCallable(i));
}
try {
List<Future<Integer>> results =
exec.invokeAll(callables);
for(Future<Integer> result: results) {
System.out.println("Got result of thread #" + result.get());
}
} catch (InterruptedException ex) {
ex.printStackTrace();
} catch (ExecutionException ex) {
ex.printStackTrace();
} finally {
exec.shutdownNow();
}
}
}
"I actually have some parts that i want to execute in parallel, and then once the results are generated, I want to merge the results in certain order." Thanks, this clarifies what you're asking.
You can run them all at once, but the important thing is to get their results in order when the threads finish their computation. Either Thread#join() them in the order in which you want to get their results, or just Thread#join() them all and then iterate through them to get their results.
// Joins the threads back to the main thread in the order we want their results.
public class ThreadOrdering {
private class MyWorker extends Thread {
final int input;
int result;
MyWorker(final int input) {
this.input = input;
}
#Override
public void run() {
this.result = input; // Or some other computation.
}
int getResult() { return result; }
}
public static void main(String[] args) throws InterruptedException {
MyWorker[] workers = new MyWorker[10];
for(int i=1; i<=10; i++) {
workers[i] = new MyWorker(i);
workers[i].start();
}
// Assume it may take a while to do the real computation in the threads.
for (MyWorker worker : workers) {
// This can throw InterruptedException, but we're just passing that.
worker.join();
System.out.println(worker.getResult());
}
}
}
Simply put, the scheduling of threads is indeterminate.
http://www.janeg.ca/scjp/threads/scheduling.html Dead domain - do not click
WaybackMachine version of the above page
The longer answer is that if you want to do this, you'll need to manually wait for each thread to complete its work before you allow another to run. Note that in this fashion, all the threads will still interleave but they won't accomplish any work until you give the go-ahead. Have a look at the synchronize reserved word.
You can chain them – that is, have the first one start the second, the second start the third, etc. They won't really be running at the same time except for a bit of overlap when each one is started.
public class ThreadOrdering
{
public static void main(String[] args)
{
MyRunnable[] threads = new MyRunnable[10];//index 0 represents thread 1;
for(int i=1; i<=10; i++)
threads[i] = new MyRunnable(i, threads);
new Thread(threads[0].start);
}
}
public class MyRunnable extends Runnable
{
int threadNumber;
MyRunnable[] threads;
public MyRunnable(int threadNumber, MyRunnable[] threads)
{
this.threadnumber = threadnumber;
this.threads = threads;
}
public void run()
{
System.out.println(threadnumber);
if(threadnumber!=10)
new Thread(threadnumber).start();
}
}
Here's a way to do it without having a master thread that waits for each result. Instead, have the worker threads share an object which orders the results.
import java.util.*;
public class OrderThreads {
public static void main(String... args) {
Results results = new Results();
new Thread(new Task(0, "red", results)).start();
new Thread(new Task(1, "orange", results)).start();
new Thread(new Task(2, "yellow", results)).start();
new Thread(new Task(3, "green", results)).start();
new Thread(new Task(4, "blue", results)).start();
new Thread(new Task(5, "indigo", results)).start();
new Thread(new Task(6, "violet", results)).start();
}
}
class Results {
private List<String> results = new ArrayList<String>();
private int i = 0;
public synchronized void submit(int order, String result) {
while (results.size() <= order) results.add(null);
results.set(order, result);
while ((i < results.size()) && (results.get(i) != null)) {
System.out.println("result delivered: " + i + " " + results.get(i));
++i;
}
}
}
class Task implements Runnable {
private final int order;
private final String result;
private final Results results;
public Task(int order, String result, Results results) {
this.order = order;
this.result = result;
this.results = results;
}
public void run() {
try {
Thread.sleep(Math.abs(result.hashCode() % 1000)); // simulate a long-running computation
}
catch (InterruptedException e) {} // you'd want to think about what to do if interrupted
System.out.println("task finished: " + order + " " + result);
results.submit(order, result);
}
}
If you need that fine-grained control, you should not use threads but instead look into using a suitable Executor with Callables or Runnables. See the Executors class for a wide selection.
A simple solution would be to use an array A of locks (one lock per thread). When thread i begins its executions, it acquires its associated lock A[i]. When it's ready to merge its results, it releases its lock A[i] and waits for locks A[0], A[1], ..., A[i - 1] to be released; then it merges the results.
(In this context, thread i means the i-th launched thread)
I don't know what classes to use in Java, but it must be easy to implement. You can begin reading this.
If you have more questions, feel free to ask.
public static void main(String[] args) throws InterruptedException{
MyRunnable r = new MyRunnable();
Thread t1 = new Thread(r,"A");
Thread t2 = new Thread(r,"B");
Thread t3 = new Thread(r,"C");
t1.start();
Thread.sleep(1000);
t2.start();
Thread.sleep(1000);
t3.start();
}
Control of thread execution order may be implemented quite easily with the semaphores. The code attached is based on the ideas presented in Schildt's book on Java (The complete reference....).
// Based on the ideas presented in:
// Schildt H.: Java.The.Complete.Reference.9th.Edition.
import java.util.concurrent.Semaphore;
class Manager {
int n;
// Initially red on semaphores 2&3; green semaphore 1.
static Semaphore SemFirst = new Semaphore(1);
static Semaphore SemSecond = new Semaphore(0);
static Semaphore SemThird = new Semaphore(0);
void firstAction () {
try {
SemFirst.acquire();
} catch(InterruptedException e) {
System.out.println("Exception InterruptedException catched");
}
System.out.println("First: " );
System.out.println("-----> 111");
SemSecond.release();
}
void secondAction() {
try{
SemSecond.acquire();
} catch(InterruptedException e) {
System.out.println("Exception InterruptedException catched");
}
System.out.println("Second: ");
System.out.println("-----> 222");
SemThird.release();
}
void thirdAction() {
try{
SemThird.acquire();
} catch(InterruptedException e) {
System.out.println("Exception InterruptedException catched");
}
System.out.println("Third: ");
System.out.println("-----> 333");
SemFirst.release();
}
}
class Thread1 implements Runnable {
Manager q;
Thread1(Manager q) {
this.q = q;
new Thread(this, "Thread1").start();
}
public void run() {
q.firstAction();
}
}
class Thread2 implements Runnable {
Manager q;
Thread2(Manager q) {
this.q = q;
new Thread(this, "Thread2").start();
}
public void run() {
q.secondAction();
}
}
class Thread3 implements Runnable {
Manager q;
Thread3(Manager q) {
this.q = q;
new Thread(this, "Thread3").start();
}
public void run() {
q.thirdAction();
}
}
class ThreadOrder {
public static void main(String args[]) {
Manager q = new Manager();
new Thread3(q);
new Thread2(q);
new Thread1(q);
}
}
This can be done without using synchronized keyword and with the help of volatile keyword. Following is the code.
package threadOrderingVolatile;
public class Solution {
static volatile int counter = 0;
static int print = 1;
static char c = 'A';
public static void main(String[] args) {
// TODO Auto-generated method stub
Thread[] ths = new Thread[4];
for (int i = 0; i < ths.length; i++) {
ths[i] = new Thread(new MyRunnable(i, ths.length));
ths[i].start();
}
}
static class MyRunnable implements Runnable {
final int thID;
final int total;
public MyRunnable(int id, int total) {
thID = id;
this.total = total;
}
#Override
public void run() {
while(true) {
if (thID == (counter%total)) {
System.out.println("thread " + thID + " prints " + c);
if(c=='Z'){
c='A';
}else{
c=(char)((int)c+1);
}
System.out.println("thread " + thID + " prints " + print++);
counter++;
} else {
try {
Thread.sleep(30);
} catch (InterruptedException e) {
// log it
}
}
}
}
}
}
Following is the github link which has a readme, that gives detailed explanation about how it happens.
https://github.com/sankar4git/volatile_thread_ordering

In multithreading: How to determine which thread stops first

Write a class named RaceHorse that extends Thread. Each RaceHorse has a name and run() method that displays the name 5000 times. Write a Java application that instantiates 2 RaceHorse objects. The last RaceHorse to finish is the loser.
This is the question.
I have written the code for the two classes two run the thread
Here are the codes:
RaceHorse
class RaceHorse extends Thread
{
public String name;
public RaceHorse(String name)
{
this.name = name;
}
public void run()
{
for(int i = 1 ; i <= 5000; i++)
{
System.out.println(i+" "+name);
}
System.out.println(name+" finished.");
}
}
Runner
class Runner{
public static void main(String args[])
{
RaceHorse obj = new RaceHorse("Lol");
RaceHorse obj2 = new RaceHorse("BOL");
Thread t = new Thread(obj);
Thread t2 = new Thread(obj2);
t.start();
t2.start();
}
}
Now my problem is I am unable to find which of the thread finishes first and which seconds, i.e. which of the horse wins and which loses.!
First off: your RaceHorse objects are themselves threads. You should be able to say obj.start(); and it'd work just as well. So remove t and t2 entirely.
Next, you'll need some way to notify the main thread about the winner.
public void run()
{
... your loop stuff ...
// this is how we're going to do the notification.
Runner.done();
}
public class Runner
{
private static RaceHorse winner = null;
synchronized static void done()
{
// Threads calling this are going to be RaceHorse objects.
// Now, if there isn't already a winner, this RaceHorse is the winner.
if (winner == null) winner = (RaceHorse) Thread.currentThread();
}
public static void main(String[] args)
{
... create the horses ...
// start the horses running
obj.start();
obj2.start();
// wait for them to finish
obj.join();
obj2.join();
System.out.println(winner.name + " wins!");
}
}
There's no doubt a better way, but one method might be to create a class (e.g. 'Trophy') that is thread safe, has a method 'getTrohpy' that only returns true on the first call, and pass a reference to an instance of Trophy to both threads.
public class StackOverflow {
public static void main(String[] args) {
RaceHorse obj = new RaceHorse("Lol");
RaceHorse obj2 = new RaceHorse("BOL");
Thread t = new Thread(obj);
Thread t2 = new Thread(obj2);
t.start();
t2.start();
}
}
class RaceHorse extends Thread
{
//public String name;
public RaceHorse(String name)
{
this.setName(name);
}
public void run()
{
for(int i = 1 ; i <= 5000; i++)
{
System.out.println(i+" "+this.getName());
try {
Thread.sleep(250);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(this.getName()+" finished.");
}
}
As cHao pointed out, RaceHorse extends Thread but you are creating a new Thread per horse. I would solve it the opposite way, by having RaceHorse implement Runnable instead.
Secondly, the solution using a synchronized method will work, but a general rule is always look for a class in java.util.concurrent that will solve the problem first. This one can be solved using an AtomicReference to ensure that only one horse takes the trophy.
Lastly, there could be a bias in favour of horse #1, if the main thread starts the horses' threads in a fixed order (this depends on the VM and on the overhead of starting a new thread on your OS.) Consider using a signal (for example a CountDownLatch) that all horses wait for before starting.
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicReference;
public class Runner {
public static void main(String args[]) {
AtomicReference<RaceHorse> winner =
new AtomicReference<RaceHorse>();
CountDownLatch startingPistol = new CountDownLatch(1);
RaceHorse horse1 = new RaceHorse("Lol", startingPistol, winner);
RaceHorse horse2 = new RaceHorse("BOL", startingPistol, winner);
Thread thread1 = new Thread(horse1);
Thread thread2 = new Thread(horse2);
thread1.start();
thread2.start();
startingPistol.countDown();
}
}
class RaceHorse implements Runnable {
private final String name;
private final CountDownLatch startingPistol;
private final AtomicReference<RaceHorse> winner;
public RaceHorse(String name,
CountDownLatch startingPistol,
AtomicReference<RaceHorse> winner)
{
this.name = name;
this.startingPistol = startingPistol;
this.winner = winner;
}
public void run()
{
try {
startingPistol.await();
for(int i = 1 ; i <= 5000; i++)
{
System.out.println(i+" "+name);
}
boolean iWon = winner.compareAndSet(null, this);
System.out.printf("%s %s.%n", name, iWon? "won": "lost");
} catch (InterruptedException ex) {
System.out.printf("%s was assasinated before the race started.%n", name);
Thread.currentThread().interrupt();
}
}
}
I am not going to write the code for you; but you should take a look at the notify method (see here) to be used.
One approach could be: once a thread has finished it will wait() for the other thread(s) to notify (or notifyAll()).
Another, more elegant solution, would consist of using a synchronized block on a shared object; the syncrhonized(obj) statement would be at the end of the run() method. Into that statement you could put a printline or any other code you would deem useful to determine who won the race.
This will work at the end of the main :
boolean alive1 = true;
boolean alive2 = true;
while (alive1 && alive2) {
alive1 = obj.isAlive();
alive2 = obj2.isAlive();
if (!alive1 && !alive2) {
// Too close to call
}
if (!alive1) {
// obj wins,
}
if (!alive2) {
// obj2 wins,
}
}
I'm late to the party, but I found this while looking for how to process the first result from a number of running threads. I think the easiest way is to use an ArrayBlockingQueue which gives you something like this.
public class RaceHorse extends Thread {
private ArrayBlockingQueue<RaceHorse> finishedRaceHorses;
public RaceHorse(String name) {
super(name);
}
public void run() {
for (int i = 1; i <= 50; i++) {
System.out.println(i + " " + getName());
}
System.out.println(getName() + " finished.");
finishedRaceHorses.offer(this);
}
public void setFinishedRaceHorses(ArrayBlockingQueue<RaceHorse> finishedRaceHorses) {
this.finishedRaceHorses = finishedRaceHorses;
}
}
public class Race {
private final List<RaceHorse> raceHorses;
public Race(List<RaceHorse> raceHorses) {
this.raceHorses = raceHorses;
}
public RaceHorse go() throws InterruptedException {
ArrayBlockingQueue<RaceHorse> finishedRaceHorses = new ArrayBlockingQueue<RaceHorse>(raceHorses.size());
for (RaceHorse raceHorse : raceHorses) {
raceHorse.setFinishedRaceHorses(finishedRaceHorses);
raceHorse.start();
}
return finishedRaceHorses.take();
}
}
public class Runner {
public static void main(String args[])
{
RaceHorse horseOne = new RaceHorse("Lol");
RaceHorse horseTwo = new RaceHorse("BOL");
Race race = new Race(Arrays.asList(horseOne, horseTwo));
try {
RaceHorse winner = race.go();
System.out.println("The winner is " + winner.getName());
} catch (InterruptedException e) {
System.out.println("The race was interrupted, maybe by a streaker?");
}
}
}
I have tried this problem and solved it using following code. There is room for improvement but for me this code worked perfectly :
1.RacingGame.java
/
package game;
import gamingObject.Horse;
import gamingObject.Race;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class RacingGame {
/**
* #param args
*/
public static Map<Integer, List<String>> raceToWinners = new HashMap<Integer, List<String>>();
public static int currentRace = 1;
public static boolean trackComplete = false;
private static boolean newTrackBegin;
private static boolean flag = true;
private static boolean race6Begin = false;
private static boolean race7Begin = false;
private static Object mutex = new Object();
private int frstHorseInNextRace = 0;
public static void main(String[] args) throws InterruptedException {
ExecutorService exeService = Executors.newFixedThreadPool(5);
/*
* Logic to conduct first 5 races (total horses/total track) so here
* total horses = 25 and tracks = 5 hence initial and compolsuary races
*/
RacingGame rg = new RacingGame();
for (int race = 1; race <= 5; race++) {
trackComplete = false;
currentRace = race;
while (!trackComplete) {
rg.startTrack();
}
}
/*
* Before 6th Race lets have right candidate for 6th race
*/
List<String> horseNames = chooseHorsesForRace6();
/*
* Race among 5 tops horses from 5 races
*/
currentRace++;
synchronized (mutex) {
while (!race6Begin) {
race(horseNames);
}
}
/*
* Choose candidates for last race 7
*/
horseNames = chooseHorsesForRace7();
currentRace++;
synchronized (mutex) {
while (!race7Begin) {
race(horseNames);
}
}
printResults();
System.exit(0);
}
private static void printResults() {
// TODO Auto-generated method stub
Iterator<Integer> iter = raceToWinners.keySet().iterator();
while (iter.hasNext()) {
int raceNum = iter.next();
StringBuffer sb = new StringBuffer();
System.out.println("Race" + raceNum + " : ");
List<String> horses = raceToWinners.get(raceNum);
for (int i = 0; i < 3; i++) {
sb.append(horses.get(i));
if (i < 2)
sb.append(",");
}
System.out.print(sb.toString());
System.out.println();
}
}
private static List<String> chooseHorsesForRace7() {
/*
* Adding First horse at first rank among 25 horses
*/
List<String> winners = new ArrayList<String>();
winners.add(raceToWinners.get(6).get(0));
raceToWinners.put(7, winners);
/*
* Taking first horses from races 2 and 3
*/
List<String> finalTrackHorses = new ArrayList<String>();
finalTrackHorses.add(raceToWinners.get(6).get(1));// firstHorse
finalTrackHorses.add(raceToWinners.get(6).get(2));// secondHorse
/*
* Rejecting all horses from race track whose first horses are at 4th
* and 5th rank of race 6
*/
for (int i = 1; i <= 5; i++) {
if (raceToWinners.get(i).contains(winners.get(0))) {
finalTrackHorses.add(raceToWinners.get(i).get(1));// thirdHorse
finalTrackHorses.add(raceToWinners.get(i).get(2));// forth horse
} else if (raceToWinners.get(i).contains(finalTrackHorses.get(1))) {
finalTrackHorses.add(raceToWinners.get(i).get(1));// fifth horse
}
}
return finalTrackHorses;
}
private static void race(List<String> horseNames) throws InterruptedException {
if (currentRace == 6)
race6Begin = true;
else
race7Begin = true;
newTrackBegin = true;
flag = true;
trackComplete = false;
while (flag) {
if (!trackComplete) {
/*
* Create thread for each horse
*
* Here taking slot of 5 horses and keep them running in a
* single loop.
*/
if (newTrackBegin) {
List<String> horses = Arrays.asList(horseNames.get(0),
horseNames.get(1), horseNames.get(2),
horseNames.get(3), horseNames.get(4));
Race r = new Race(horses);
r.start();
}
newTrackBegin = false;
mutex.wait(1);
} else if (trackComplete) {
mutex.notify();
flag = false;
}
}
}
private static List<String> chooseHorsesForRace6() {
List<String> lstHorses = new ArrayList<String>();
for (int i = 1; i <= 5; i++) {
/*
* Take only 1st Position Holders of first 5 races
*/
lstHorses.add(raceToWinners.get(i).get(0));
}
return lstHorses;
}
public Map<Integer, List<String>> getRaceToWinners() {
return raceToWinners;
}
public static synchronized void addTrackWinnerInList(String horseName) {
List<String> horses = raceToWinners.get(currentRace);
if (horses == null) {
List<String> raceHorses = new ArrayList<String>();
raceHorses.add(horseName);
raceToWinners.put(currentRace, raceHorses);
} else {
horses.add(horseName);
raceToWinners.put(currentRace, horses);
}
if (raceToWinners.get(currentRace) != null
&& raceToWinners.get(currentRace).size() == 5) {
trackComplete = true;
}
}
public static boolean isTrackComplete(){
return trackComplete;
}
public void startTrack() throws InterruptedException {
// TODO Auto-generated method stub
synchronized (mutex) {
flag = true;
newTrackBegin = true;
trackComplete = false;
while (!trackComplete) {
/*
* Create thread for each horse
*
* Here taking slot of 5 horses and keep them running in a
* single loop.
*/
if (newTrackBegin) {
List<String> horses = Arrays.asList("Horse"
+ (++frstHorseInNextRace), "Horse"
+ (++frstHorseInNextRace), "Horse"
+ (++frstHorseInNextRace), "Horse"
+ (++frstHorseInNextRace), "Horse"
+ (++frstHorseInNextRace));
Race r = new Race(horses);
r.start();
}
newTrackBegin = false;
}
}
}
}
2.Horse.java
package gamingObject;
import game.RacingGame;
public class Horse extends Thread{
String horseName;
public Horse(String horseName){
this.horseName = horseName;
}
#Override
public void run() {
for (int i = 0; i < 5; i++) {
try {
sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
RacingGame.addTrackWinnerInList(this.horseName);
}
}
3.Race.java
package gamingObject;
import game.RacingGame;
import java.util.List;
public class Race extends Thread {
List<String> horses;
private boolean flag = true;
private Object obj = new Object();
public Race(List<String> horses) {
this.horses = horses;
}
public void startRace() {
synchronized (obj) {
run();
}
}
#Override
public void run() {
synchronized (obj) {
boolean newTrackBegin = true;
while (!RacingGame.isTrackComplete()) {
/*
* Create thread for each horse
*
* Here taking slot of 5 horses and keep them running in a
* single loop.
*/
if (newTrackBegin) {
Horse h1 = new Horse(horses.get(0));
Horse h2 = new Horse(horses.get(1));
Horse h3 = new Horse(horses.get(2));
Horse h4 = new Horse(horses.get(3));
Horse h5 = new Horse(horses.get(4));
Thread t1 = new Thread(h1);
Thread t2 = new Thread(h2);
Thread t3 = new Thread(h3);
Thread t4 = new Thread(h4);
Thread t5 = new Thread(h5);
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
newTrackBegin = false;
}else{
if(!RacingGame.isTrackComplete()){
try {
obj.wait(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
obj.notify();
}
}
}
}
}
}

How can a Thread return a value after finishing its job?

Let's say we have this simple example:
public Example extends Thread{
String temp;
public Example(){
}
#Override
public void run(){
.
.
.
.
temp = "a_value";
}
public static void main(String[] args) {
Example th = new Example();
th.start();
}
}
How can the Thread after finishing its job return me the String temp?
Make use of the (relatively) new Callable<T> instead of Runnable (available in 1.5 and newer versions):
Here is a (simple) example:
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Main {
public static void main(final String[] argv) {
final ExecutorService service;
final Future<String> task;
service = Executors.newFixedThreadPool(1);
task = service.submit(new Foo());
try {
final String str;
// waits the 10 seconds for the Callable.call to finish.
str = task.get(); // this raises ExecutionException if thread dies
System.out.println(str);
} catch(final InterruptedException ex) {
ex.printStackTrace();
} catch(final ExecutionException ex) {
ex.printStackTrace();
}
service.shutdownNow();
}
}
class Foo implements Callable<String> {
public String call() {
try {
// sleep for 10 seconds
Thread.sleep(10 * 1000);
} catch(final InterruptedException ex) {
ex.printStackTrace();
}
return ("Hello, World!");
}
}
Look at Future interface javadoc. It has sample usage showing you how to do this.
You can achieve this by the Observer pattern.
on finishing the thread notifies all listeners that it's finished and they can retrieve the value (through a getter). Or it can even already send the computed value.
Or you can use a task, see FutureTask, a runnable ( indeed as stated below a Callable ) that returns a result and can throw exceptions.
If you don't want to swap the solution to use Callable objects then you can use also queues and return the result from the threads that way.
I re-wrote your example like this:
import java.util.PriorityQueue;
import java.util.Queue;
public class GetResultFromThread {
public static void main(String[] args) throws Exception {
Queue<String> queue = new PriorityQueue<String>();
int expectedResults = 2;
for (int i = 0; i < expectedResults; i++) {
new Example(queue).start();
}
int receivedResults = 0;
while (receivedResults < expectedResults) {
if (!queue.isEmpty()) {
System.out.println(queue.poll());
receivedResults++;
}
Thread.sleep(1000);
}
}
}
class Example extends Thread {
private final Queue<String> results;
public Example(Queue<String> results) {
this.results = results;
}
#Override
public void run() {
results.add("result from thread");
}
}
Note that you shall think of synchronization and concurrency!

Categories