Tribal Fusion Interview Question
Software Engineer / DevelopersCountry: India
Interview Type: Phone Interview
Java?
C# looks like this:
using System;
namespace InterviewQuestion
{
class Program
{
class JobHolder
{
private object syncBlock = new object();
private System.Random rand = new Random();
private bool isJob1Finished = false;
public void Job1Start()
{
lock (this.syncBlock)
{
isJob1Finished = true; // might as well set it early since we have the mutex
System.Console.WriteLine("JOB1 progress...");
System.Threading.Thread.Sleep(100);
System.Console.WriteLine("JOB1 progress...");
System.Threading.Thread.Sleep(200);
System.Console.WriteLine("JOB1 progress...");
System.Threading.Thread.Sleep(200);
System.Console.WriteLine("JOB1 progress...");
System.Threading.Thread.Sleep(1000);
System.Console.WriteLine("JOB1 finished");
}
}
public void Job2Start()
{
int waitTime = 1000;
// thread waits forever until getting the indication job1 finished
while (true)
{
lock (this.syncBlock)
{
if (isJob1Finished)
{
System.Threading.Thread.Sleep(100);
System.Console.WriteLine("JOB2 progress...");
System.Threading.Thread.Sleep(100);
System.Console.WriteLine("JOB2 progress...");
System.Threading.Thread.Sleep(200);
System.Console.WriteLine("JOB2 progress...");
System.Threading.Thread.Sleep(300);
System.Console.WriteLine("JOB2 finished");
return;
}
//also accessing the rand variable with the lock
waitTime = rand.Next(3000);
}
System.Console.WriteLine("JOB2 waiting " + waitTime + "ms");
System.Threading.Thread.Sleep(waitTime);
}
}
}
static void Main(string[] args)
{
JobHolder j = new JobHolder();
System.Threading.ThreadStart op1 = new System.Threading.ThreadStart(j.Job1Start);
System.Threading.ThreadStart op2 = new System.Threading.ThreadStart(j.Job2Start);
System.Threading.Thread t1 = new System.Threading.Thread(op1);
System.Threading.Thread t2 = new System.Threading.Thread(op2);
t2.Start();
t1.Start();
t1.Join();
t2.Join();
//System.Threading.WaitHandle.WaitAll();
System.Console.WriteLine("Experiment finished! Enter any key to continue...");
System.Console.ReadKey();
}
}
}
You can also use a Latch in Java 6.0 onwards, here is the sample from Java documentation:
Sample usage: Here is a pair of classes in which a group of worker threads use two countdown latches:
The first is a start signal that prevents any worker from proceeding until the driver is ready for them to proceed;
The second is a completion signal that allows the driver to wait until all workers have completed.
class Driver { // ...
void main() throws InterruptedException {
CountDownLatch startSignal = new CountDownLatch(1);
CountDownLatch doneSignal = new CountDownLatch(N);
for (int i = 0; i < N; ++i) // create and start threads
new Thread(new Worker(startSignal, doneSignal)).start();
doSomethingElse(); // don't let run yet
startSignal.countDown(); // let all threads proceed
doSomethingElse();
doneSignal.await(); // wait for all to finish
}
}
class Worker implements Runnable {
private final CountDownLatch startSignal;
private final CountDownLatch doneSignal;
Worker(CountDownLatch startSignal, CountDownLatch doneSignal) {
this.startSignal = startSignal;
this.doneSignal = doneSignal;
}
public void run() {
try {
startSignal.await();
doWork();
doneSignal.countDown();
} catch (InterruptedException ex) {} // return;
}
void doWork() { ... }
}
i forgot to add this. I am sorry but interviewer has explicitly said without using join method
This solution does not depend on join; so, removing it still gets the intended effect.
Replace that section with the following:
//... mostly the same ...
t2.Start();
t1.Start();
//t1.Join(); Requested we do not join
//t2.Join(); Jobs still execute in order correctly
System.Console.WriteLine("Main thread exiting early since there is no join. Other threads will execute jobs in the correct order.");
}
}
}
If you are referring to java, then your conclusion might be wrong
if you start two threads one after the other, the start in a separat thread of execution. lets assume t1 takes 2 days for execution and t2 takes an hour, in your case t2 completes before t1 completes, using join is the right way to do it.
If your are using Java, in the beginning of T2 we can use
so that T2 waits for T1 to finish execution.
- wirelesszzz January 17, 2012