Reputation: 353
I have multiple threads printing data. All the data does print; however, they are not in order. Meaning Thread 2 starts printing while Thread 1 is not done yet, which causes inconsistency. How do I guarantee consistency ? Meaning Thread 2 can print once Thread 1 is done.
Upvotes: 1
Views: 379
Reputation: 2771
From your comments, you are looking to achieve 1 1 1 1 2 2 2 2
so what you'd need to do is actually wait for Thread1 to complete, then start Thread2, like this:
Thread1 thread1 = new Thread1();
Thread2 thread2 = new Thread2();
thread1.start();
thread1.join(); // This waits for Thread1 to finish before starting Thread2
thread2.start();
however, if you want to have both threads start, but have Thread2 wait part way through its processing, while waiting for Thread1 to complete - this can be done with a few techniques - one in particular comes to mind - using Semaphore.
Example:
Ok, firstly define your thread constructors to accept a Semaphore, thus:
// Thread2 would be identical wrt the semaphore
public Thread1(Semaphore semaphore) throws InterruptedException
{
this.semaphore = semaphore; // store semaphore locally
semaphore.acquire(2);
}
Thread1's run method would look like this:
public void run()
{
// .... processing...
// ... print stuff
System.out.println("1 1 1 1");
semaphore.release(); // release 1 permit, allowing thread2 to continue
// ... more processing
semaphore.release(); // release last permit.
}
Thread2's run method would look something akin to this:
public void run()
{
int permits = 2;
try
{
// .... processing...
semaphore.acquire(1); // acquire one more permit (will block until Thread1 releases one)
permits++;
// ... print stuff
System.out.println("2 2 2 2");
// ... more processing
}
catch (InterruptedException ie)
{
// interrupted
}
semaphore.release(permits); // release permits.
}
Now, setting up the threads would be done like this:
try
{
Semaphore semaphore = new Semaphore(4); // 4 permit semaphore
Thread1 thread1 = new Thread1(semaphore);
Thread2 thread2 = new Thread2(semaphore);
thread1.start();
thread2.start();
semaphore.acquire(4);
}
catch (InterruptedException ie)
{
// interrupt logic...
}
Upvotes: 0
Reputation: 76898
You can not randomly print from multiple threads and expect any order.
If you need output in an ordered fashion then you're going to have to either synchronize the threads (thus defeating the purpose of having multiple threads) or have the threads pass back the information to output back to the main thread so it can handle ordering and outputting it.
Edit: Because I'm bored.
If you're trying to parallelize some work via threads then output the results, you need to have the threads communicate the product of their work back to the main thread and have it do the output. One approach to this is to use queues (this is simple example that relies on the thread order - you may need to get all the results and correlate/sort/etc):
public class Worker implements Runnable
{
private ConcurrentLinkedQueue<Integer> outputQueue;
public Worker(ConcurrentLinkedQueue<Integer> outputQueue)
{
this.outputQueue = outputQueue;
}
@Override
public void run()
{
// Do whatever it is you're doing
...
// place result on queue
outputQueue.add(result);
}
}
public class Main
{
static void main(String[] args)
{
ArrayList<ConcurrentLinkedQueue<Integer>> myQueues =
new ArrayList<ConcurrentLinkedQueue<Integer>>();
Thread[] myThreads = new Thread[numThreads];
// Create queue, create thread with Worker(queue),
// start thread
for (int i = 0; i < numThreads; i++)
{
ConcurrentLinkedQueue<Integer> queue =
new ConcurrentLinkedQueue<Integer>();
myQueues.add(queue);
myThreads[i] = new Thread(new Worker(queue)).start();
}
// Wait for all threads to finish, print their results
for (int i = 0; i < numThreads; i++)
{
join(myThreads[i]);
// Get the queue for the thread we just joined,
// pull off each result and output
Integer j;
while ((j = myQueues.get(i).poll()) != null)
{
System.out.println(j);
}
}
}
}
This is off the top of my head, but that's the general approach
Upvotes: -1
Reputation: 9337
So, here's what you want to do (pseudo-code):
String results[2];
Thread1 thread1 = new Thread1() {
public void run() {
// do stuff; collect output
results[0] = output
}
};
Thread2 thread1 = new Thread1() {
public void run() {
// do stuff; collect output
results[1] = output
}
};
thread1.start();
thread2.start();
thread1.join();
thread2.join();
print result[0];
print result[1];
There are better ways of doing above using classes from java.util.concurrent, but this should give you an idea
Upvotes: 1
Reputation: 2115
If you want the code executed by Thread 1 to finish before running Thread 2, then you don't want threads. You might want to take a look at Java's ExecutorService
. Specifically, Executors. newSingleThreadExecutor()
. This will allow you to schedule tasks to be run in another thread, but insure that they are run sequentially.
Upvotes: 1
Reputation: 7344
You'd have to save Thread 2 output and print it until Thread 1 is one. Executing them in order as suggested would work too but then, why have Thread's?
Upvotes: 0
Reputation: 1825
We cannot calculate when a thread is going to run and complete the execution. It completely depends on the CPU. What you can do is have a flag variable at the end of first thread being updated to a value and check for that value before second thread executes.
Upvotes: 0
Reputation: 2568
Once the run method is done in thread one have it call something in thread two to let it know that it can print
Upvotes: 0
Reputation: 1560
this is how threads work.. if you start two thread it will go something like this 1 2 1 2 1 2 1 2
Upvotes: 0