Salesforce Interview Question
Software EngineersCountry: United States
public class CareerCup4783236498587648 {
public static void main(String[] args) {
final Lock lock = new ReentrantLock();
final Condition condition = lock.newCondition();
ThreadId threadId = new CareerCup4783236498587648.ThreadId();
threadId.setId(1);
Thread t1 = setThread(lock, condition, 1, 2, threadId);
Thread t2 = setThread(lock, condition, 2, 3, threadId);
Thread t3 = setThread(lock, condition, 3, 1, threadId);
t1.start();
t2.start();
t3.start();
}
private static class ThreadId {
private int id;
public ThreadId(){}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
private static Thread setThread(final Lock lock, final Condition condition, int actualThreadId, int nextThreadId, ThreadId threadId) {
Thread thread = new Thread() {
@Override
public void run() {
while (true) {
lock.lock();
try {
while (threadId.getId() != actualThreadId)
try {
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("" + actualThreadId);
threadId.setId(nextThreadId);
condition.signalAll();
} finally {
lock.unlock();
}
}
}
};
return thread;
}
}
I like your solution. It provides for the Open Close OO design principle while the solution I proposed is not.
One thing that I noticed though when I tried to run your code on Oracle Java 7 JVM is
Error:(44, 32) java: local variable threadId is accessed from within inner class; needs to be declared final
So you need to change the method declaration to
private static Thread setThread(final Lock lock, final Condition condition, int actualThreadId, int nextThreadId, final ThreadId threadId)
You are right! However all the method parameters should be final. My Eclipse -> Save Action didnt work properly that time...
Here is my take using C
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h> /* Semaphore */
#define THREADS 3
sem_t mutex1;
sem_t mutex2;
sem_t mutex3;
//function prototypes
void * monitor_thread1 (void* data);
void * monitor_thread2 (void* data);
void * monitor_thread3 (void* data);
int main(int argc, char **argv)
{
pthread_t tid[THREADS];
sem_init(&mutex1, 0, 1);
sem_init(&mutex2, 0, 0);
sem_init(&mutex3, 0, 0);
pthread_create(&tid[2], NULL,monitor_thread3, NULL);
pthread_create(&tid[0], NULL,monitor_thread1, NULL);
pthread_create(&tid[1], NULL,monitor_thread2, NULL);
pthread_join(tid[0], NULL);
pthread_join(tid[1], NULL);
pthread_join(tid[2], NULL);
sem_destroy(&mutex1);
sem_destroy(&mutex2);
sem_destroy(&mutex3);
return 0;
}
void * monitor_thread1 (void* data)
{
int i,j=1;
for (i=0;i<10;i++){
sem_wait(&mutex1); /* down semaphore */
printf("%d \n",j);
sem_post(&mutex2); /* down semaphore */
}
//sleep(1);
return;
}
void * monitor_thread2 (void* data)
{
int i,j=2;
for (i=0;i<10;i++){
sem_wait(&mutex2); /* down semaphore */
printf("%d \n",j);
sem_post(&mutex3); /* down semaphore */
//sleep(1);
}
return;
}
void * monitor_thread3 (void* data)
{
int i,j=3;
for (i=0;i<10;i++){
sem_wait(&mutex3); /* down semaphore */
printf("%d \n",j);
sem_post(&mutex1); /* down semaphore */
}
//sleep(1);
return;
}
Windows C++ code
#include <stdafx.h>
#include <iostream>
#include <thread>
#include <mutex>
#include <vector>
#include <condition_variable>
using namespace std;
#define MAXNUM 90
int num = 1;
condition_variable oneCondition;
condition_variable twoCondition;
condition_variable thirdCondition;
mutex guard;
void thread3()
{
while (num <= MAXNUM)
{
if (num % 3 != 0)
{
unique_lock<mutex> lck(guard);
thirdCondition.wait(lck);
}
//cout << "Thread3 : " << num << endl;
cout << 3;
++num;
oneCondition.notify_one();
}
}
void thread2()
{
while (num <= MAXNUM-1)
{
if (num % 3 != 2)
{
unique_lock<mutex> lck(guard);
twoCondition.wait(lck);
}
//cout << "Thread2 : " << num<<endl;
cout << 2;
++num;
thirdCondition.notify_one();
}
}
void thread1()
{
while (num <= MAXNUM-2)
{
if (num % 3 != 1)
{
unique_lock<mutex> lck(guard);
oneCondition.wait(lck);
}
//cout << "Thread1 : " << num << endl;;
cout << 1;
++num;
twoCondition.notify_one();
}
}
int main()
{
thread t1(thread1), t2(thread2), t3(thread3);
t1.join(), t2.join(), t3.join();
getchar();
}
Well, how about they all access an integer and check it's value, if it is 1 - first thread allowed to print and after printing change it to "2" , and so on ?
or am I missing something here?
This works and here is C# code for it
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Testyourskills
{
/// <summary>
/// There are three threads in a process. The first thread prints 1 1 1 …,
/// the second one prints 2 2 2 …, and the third one prints 3 3 3 … endlessly.
/// How do you schedule these three threads in order to print 1 2 3 1 2 3 …?
/// </summary>
/// <author>Pramod Kumar Chandoria</author>
public class ThreeThreadsInSync
{
private static object Lock = new object();
internal static int State = 1;
public static void Main(string[] arguments)
{
var task1 = new Thread(MethodA);
var task2 = new Thread(MethodB);
var task3 = new Thread(MethodC);
task1.Start();
task2.Start();
task3.Start();
}
internal static void MethodA()
{
while(true)
{
if (State == 1)
{
lock (Lock)
{
State = 2;
Console.Write("1 ");
}
}
}
}
internal static void MethodB()
{
while (true)
{
if (State == 2)
{
lock (Lock)
{
State = 3;
Console.Write("2 ");
Thread.Sleep(100);
}
}
}
}
internal static void MethodC()
{
while (true)
{
if (State == 3)
{
lock (Lock)
{
State = 1;
Thread.Sleep(1000);
Console.Write("3 ");
}
}
}
}
}
}
package com.salesforce;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPrintSequence {
public static void main(String[] args) {
ExecutorService threadPool = Executors.newFixedThreadPool(3);
PrintNumber one = new PrintNumber("1");
PrintNumber two = new PrintNumber("2", one);
PrintNumber three = new PrintNumber("3", two);
one.parent = three;
threadPool.execute(one);
threadPool.execute(two);
threadPool.execute(three);
}
}
class PrintNumber implements Runnable {
public String number;
public Runnable parent;
public PrintNumber(String number ){
this.number = number;
}
public PrintNumber(String number , Runnable parent){
this.number = number;
this.parent = parent;
}
public void run(){
while (true) {
try {
System.out.println(number);
synchronized (this) {
notify();
}
synchronized (parent) {
parent.wait();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalMonitorStateException ex) {
ex.printStackTrace();
}
}
}
}
public class Thrd1 extends Thread {
private sobj s=null;
public Thrd1(sobj s){
this.s=s;
}
public void run(){
while(true){
s.put(1);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public class Thrd2 extends Thread{
private sobj s=null;
public Thrd2(sobj s){
this.s=s;
}
public void run(){
while(true){
s.put(2);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public class Thrd3 extends Thread {
private sobj s=null;
public Thrd3(sobj s){
this.s=s;
}
public void run(){
while(true){
s.put(3);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public class sobj {
private volatile int prv=2,act;
public synchronized void put(int k1){
while(prv==k1){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if(act+1==k1){
System.out.print(k1);
}
act=k1;
prv=k1;
if(act==3){
act=0;
}
notifyAll();
}
}
public class tm {
/**
* @param args
*/
public static void main(String[] args) {
sobj s=new sobj();
Thrd1 t1=new Thrd1(s);
Thrd2 t2=new Thrd2(s);
Thrd3 t3=new Thrd3(s);
t1.start();
t2.start();
t3.start();
}
}
package com.threadInterviewquestions;
public class Thread1 {
static Object [] obj ={new Object(),new Object(),new Object() };
static boolean thread1=false;
static boolean thread2=false;
static boolean thread3=false;
static void method1()
{ while(true){
// System.out.println("value of Thread3="+thread3);
while(!thread3)
{
synchronized (obj[0]) {
try {
obj[0].wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
System.out.print(1+" ");
thread3=false;
thread1=true;
synchronized (obj[1]) {
obj[1].notify();
}
}
}
static void method2()
{while(true){
//System.out.println("value of Thread1="+thread1);
while(!thread1)
{
synchronized (obj[1]) {
try {
obj[1].wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} System.out.print(2+" ");
thread1=false;
thread2=true;
synchronized (obj[2]) {
obj[2].notify();
}
}
}
static void method3()
{ while(true){
//System.out.println("value of Thread2="+thread2);
while(!thread2)
{
synchronized (obj[2]) {
try {
obj[2].wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
System.out.print(3+" ");
thread2=false;
thread3=true;
synchronized (obj[0]) {
obj[0].notify();
}
}
}
public static void main(String[] args) {
Thread th1 =new Thread(new Runnable() {
public void run() {
// TODO Auto-generated method stub
method1();
}
});
Thread th2 =new Thread(new Runnable() {
public void run() {
// TODO Auto-generated method stub
method2();
}
});
Thread th3 =new Thread(new Runnable() {
public void run() {
// TODO Auto-generated method stub
method3();
}
});
thread3=true;
th1.start();
th2.start();
th3.start();
}
}
package com.threadInterviewquestions;
public class Thread1 {
static Object [] obj ={new Object(),new Object(),new Object() };
static boolean thread1=false;
static boolean thread2=false;
static boolean thread3=false;
static void method1()
{ while(true){
// System.out.println("value of Thread3="+thread3);
while(!thread3)
{
synchronized (obj[0]) {
try {
obj[0].wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
System.out.print(1+" ");
thread3=false;
thread1=true;
synchronized (obj[1]) {
obj[1].notify();
}
}
}
static void method2()
{while(true){
//System.out.println("value of Thread1="+thread1);
while(!thread1)
{
synchronized (obj[1]) {
try {
obj[1].wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} System.out.print(2+" ");
thread1=false;
thread2=true;
synchronized (obj[2]) {
obj[2].notify();
}
}
}
static void method3()
{ while(true){
//System.out.println("value of Thread2="+thread2);
while(!thread2)
{
synchronized (obj[2]) {
try {
obj[2].wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
System.out.print(3+" ");
thread2=false;
thread3=true;
synchronized (obj[0]) {
obj[0].notify();
}
}
}
public static void main(String[] args) {
Thread th1 =new Thread(new Runnable() {
public void run() {
// TODO Auto-generated method stub
method1();
}
});
Thread th2 =new Thread(new Runnable() {
public void run() {
// TODO Auto-generated method stub
method2();
}
});
Thread th3 =new Thread(new Runnable() {
public void run() {
// TODO Auto-generated method stub
method3();
}
});
thread3=true;
th1.start();
th2.start();
th3.start();
}}
Here is the working code in java. By updating the constant value "TOTAL_THREADS", we can instantiate 'n' number of threads that co-ordinates with each other to print the numbers in order 1,2,3,4,...n,1,2,3,4,...n........
import java.util.concurrent.locks.*;
class PrintTest
{
private Lock _Lock;
private int _ThreadReadyCount;
private final int TOTAL_THREADS = 5;
private Condition _Ready;
private Condition _Condition[];
synchronized public void IncreaseReadyCount()
{
_ThreadReadyCount = _ThreadReadyCount + 1;
if( _ThreadReadyCount == TOTAL_THREADS ) _Ready.signalAll();
}
synchronized public int GetThreadReadyCount()
{
return _ThreadReadyCount;
}
public PrintTest()
{
_Lock = new ReentrantLock();
_ThreadReadyCount = 0;
_Ready = _Lock.newCondition();
_Condition = new Condition[TOTAL_THREADS];
for(int i=1; i<=TOTAL_THREADS; i++)
{
_Condition[i-1] = _Lock.newCondition();
}
}
public void StartPrinting(int iStartThreadIndex) throws InterruptedException
{
_Lock.lock();
try
{
RunnableDemo Demos[] = new RunnableDemo[TOTAL_THREADS];
for(int i=1; i<=TOTAL_THREADS; i++)
{
Demos[i-1] = new RunnableDemo(i, this);
Demos[i-1].start();
}
_Ready.await(); //when all the threads are ready
System.out.println("All the three threads are ready......");
//_Condition[0].signalAll();
int Index = (int) (Math.random() * TOTAL_THREADS);
_Condition[iStartThreadIndex].signalAll();
}
finally
{
_Lock.unlock();
}
}
public void PrintRandomNumbers(int iMaxValue, int iTotalNumbers)
{
System.out.println("Randome numbers.....");
for(int i=1; i<=iTotalNumbers; i++)
System.out.println(i + ") " + (int)(Math.random() * iMaxValue));
}
public void PrintThread(int InputValue) throws InterruptedException
{
_Lock.lock();
try
{
System.out.println("Print thread is invoked from Thread-" + InputValue);
IncreaseReadyCount();
while(true)
{
_Condition[InputValue-1].await();
System.out.println(InputValue);
if( InputValue < TOTAL_THREADS )
_Condition[InputValue].signalAll();
else
_Condition[0].signalAll();
}
}
finally
{
_Lock.unlock();
}
}
}
class RunnableDemo implements Runnable
{
private PrintTest _printTest;
private Thread t;
private int _inputValue;
RunnableDemo(int iValue, PrintTest pTest)
{
_inputValue = iValue;
_printTest = pTest;
}
public void run()
{
try
{
_printTest.PrintThread(_inputValue);
}
catch(InterruptedException e)
{
}
}
public void start ()
{
if (t == null)
{
t = new Thread (this);
t.start ();
}
}
}
public class Test_SignalAll
{
public static void main(String args[])
{
String option = args[0];
if( option.equals("-h") || option.equals("-H") || option.equals("-HELP") )
{
System.out.println("The program can be invoked with following arguments...");
System.out.println("RANDOM <MAX VALUE> <TOTAL NUMBERS>");
System.out.println("PRINT <MAX VALUE>");
}
PrintTest oPrintTest = new PrintTest();
if( option.equals("RANDOM") )
{
if( args.length == 3 )
{
try
{
int iMaxValue = Integer.parseInt(args[1]);
int iTotal = Integer.parseInt(args[2]);
oPrintTest.PrintRandomNumbers(iMaxValue, iTotal);
}
catch(NumberFormatException e)
{
System.out.println("Invalid type of arguments....Please try as follows....");
System.out.println("RANDOM <MAX VALUE as integer> <TOTAL NUMBERS as integer>");
}
}
else
{
System.out.println("Invalid number of arguments....Please try as follows....");
System.out.println("RANDOM <MAX VALUE> <TOTAL NUMBERS>");
}
}
try
{
if( option.equals("PRINT") )
{
if( args.length == 2 )
{
try
{
int iMaxValue = Integer.parseInt(args[1]);
oPrintTest.StartPrinting(iMaxValue);
}
catch(NumberFormatException e)
{
System.out.println("Invalid type of arguments....Please try as follows....");
System.out.println("PRINT <MAX Number of Threads as integer>");
}
}
else
{
System.out.println("Invalid number of arguments....Please try as follows....");
System.out.println("PRINT <MAX VALUE>");
}
}
}
catch(InterruptedException e)
{
}
}
}
static void Main(string[] args) {
AutoResetEvent e1 = new AutoResetEvent(true);
AutoResetEvent e2 = new AutoResetEvent(false);
AutoResetEvent e3 = new AutoResetEvent(false);
Thread t1 = new Thread(
() => {
e1.WaitOne();
for (int i = 0; i < 3; i++) {
System.Console.WriteLine(1);
e2.Set();
if (i == 2) {
return;
}
e1.WaitOne();
}
}
);
Thread t2 = new Thread(
() => {
e2.WaitOne();
for (int i = 0; i < 3; i++) {
System.Console.WriteLine(2);
e3.Set();
if (i == 2) {
return;
}
e2.WaitOne();
}
}
);
Thread t3 = new Thread(
() => {
e3.WaitOne();
for (int i = 0; i < 3; i++) {
System.Console.WriteLine(3);
e1.Set();
if (i == 2) {
return;
}
e3.WaitOne();
}
}
);
t1.Start();
t2.Start();
t3.Start();
//e1.Set(); // not required because while declaring we set it to "true"
}
static void Main(string[] args) {
AutoResetEvent e1 = new AutoResetEvent(true);
AutoResetEvent e2 = new AutoResetEvent(false);
AutoResetEvent e3 = new AutoResetEvent(false);
Thread t1 = new Thread(
() => {
e1.WaitOne();
for (int i = 0; i < 3; i++) {
System.Console.WriteLine(1);
e2.Set();
if (i == 2) {
return;
}
e1.WaitOne();
}
}
);
Thread t2 = new Thread(
() => {
e2.WaitOne();
for (int i = 0; i < 3; i++) {
System.Console.WriteLine(2);
e3.Set();
if (i == 2) {
return;
}
e2.WaitOne();
}
}
);
Thread t3 = new Thread(
() => {
e3.WaitOne();
for (int i = 0; i < 3; i++) {
System.Console.WriteLine(3);
e1.Set();
if (i == 2) {
return;
}
e3.WaitOne();
}
}
);
t1.Start();
t2.Start();
t3.Start();
//e1.Set(); // not required because while declaring we set it to "true"
}
Try running below code:
package test.careercup.threads;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TestCondition {
public static void main(String[] args) {
PrintSequenceSingleMethod p = new PrintSequenceSingleMethod();
Thread1 thred1 = new Thread1(p, 1);
Thread1 thred2 = new Thread1(p, 2);
Thread1 thred3 = new Thread1(p, 3);
ExecutorService exec = Executors.newFixedThreadPool(3);
exec.execute(thred1);
exec.execute(thred2);
exec.execute(thred3);
exec.shutdown();
}
}
class Thread1 implements Runnable {
PrintSequenceSingleMethod obj;
int number;
Thread1(PrintSequenceSingleMethod obj, int n) {
this.obj = obj;
this.number = n;
}
@Override
public void run() {
for (;;)
obj.printNumber(number);
}
}
package test.careercup.threads;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class PrintSequenceSingleMethod {
public volatile int stateNumber = 1;
public final ReentrantLock lock = new ReentrantLock();
public final Condition condition1 = lock.newCondition();
public final Condition condition2 = lock.newCondition();
public void printNumber(int number) {
lock.lock();
try {
while (!(stateNumber == number))
condition1.await();
System.out.print(number);
stateNumber = number + 1;
condition1.signalAll();
if (stateNumber > 3) {
stateNumber = 1;
System.out.print("\n");
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
Main class App.java
public class App
{
public static void main( String[] args ) {
ConsoleManager consoleManager = new ConsoleManager();
NumberPrinter numberPrinter1 = new NumberPrinter(1, consoleManager);
NumberPrinter numberPrinter2 = new NumberPrinter(2, consoleManager);
NumberPrinter numberPrinter3 = new NumberPrinter(3, consoleManager);
ExecutorService executor3 = Executors.newSingleThreadExecutor();
ExecutorService executor1 = Executors.newSingleThreadExecutor();
ExecutorService executor2 = Executors.newSingleThreadExecutor();
executor1.execute(numberPrinter1);
executor2.execute(numberPrinter2);
executor3.execute(numberPrinter3);
}
}
NumberPrinter.java
public class NumberPrinter implements Runnable {
private ConsoleManager consoleManager;
private int x;
public NumberPrinter(int x, ConsoleManager consoleManager) {
this.x = x;
this.consoleManager = consoleManager;
}
@Override
public void run() {
while (true) {
consoleManager.print(x);
}
}
}
ConsoleManager.java
public class ConsoleManager {
private int previouslyPrintedNumber = 0;
private Lock lock = new ReentrantLock();
public void print(int x) {
lock.lock();
switch (x) {
case 1:
if (previouslyPrintedNumber == 0 || previouslyPrintedNumber == 3) {
previouslyPrintedNumber = x;
System.out.print(x + " ");
}
break;
case 2:
if (previouslyPrintedNumber == 1) {
previouslyPrintedNumber = x;
System.out.print(x + " ");
}
break;
case 3:
if (previouslyPrintedNumber == 2) {
previouslyPrintedNumber = x;
System.out.print(x + " ");
}
break;
default:
throw new RuntimeException("Unrecognized input " + x);
}
lock.unlock();
}
}
import java.util.List;
import java.util.ArrayList;
public class Manager {
List<Thread> printers;
Integer currentPrinterNumber = 1;
public static void main (String[] args) throws Exception {
Manager aManager = new Manager();
aManager.initPrinters();
aManager.startPrinters();
}
public void initPrinters () {
printers = new ArrayList<Thread>();
for (int i = 1; i < 4; ++i) {
Printer p = new Printer(i, this);
Thread t = new Thread(p);
printers.add(t);
}
}
public void startPrinters () throws Exception {
for (Thread p : printers) {
p.start();
Thread.sleep(100);
}
}
public boolean isMyTurn (Printer p) {
if (p.getInt() == currentPrinterNumber) {
return true;
}
return false;
}
public void complete () {
synchronized (this) {
currentPrinterNumber++;
if (currentPrinterNumber > printers.size()) {
currentPrinterNumber = 1;
}
notifyAll();
}
}
}
class Printer implements Runnable {
private Integer myInt;
private Manager myManager;
Integer getInt () {
return myInt;
}
public Printer (Integer i, Manager m) {
myInt = i;
myManager = m;
}
public void run () {
synchronized (myManager) {
while (true) {
try {
if (myManager.isMyTurn(this)) {
printMyInt();
}
myManager.wait();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
}
private void printMyInt () {
synchronized (myManager) {
System.out.print(myInt + " ");
myManager.complete();
}
}
}
import java.util.List;
import java.util.ArrayList;
public class Manager {
List<Thread> printers;
Integer currentPrinterNumber = 1;
public static void main (String[] args) throws Exception {
Manager aManager = new Manager();
aManager.initPrinters();
aManager.startPrinters();
}
public void initPrinters () {
printers = new ArrayList<Thread>();
for (int i = 1; i < 4; ++i) {
Printer p = new Printer(i, this);
Thread t = new Thread(p);
printers.add(t);
}
}
public void startPrinters () throws Exception {
for (Thread p : printers) {
p.start();
Thread.sleep(100);
}
}
public boolean isMyTurn (Printer p) {
if (p.getInt() == currentPrinterNumber) {
return true;
}
return false;
}
public void complete () {
synchronized (this) {
currentPrinterNumber++;
if (currentPrinterNumber > printers.size()) {
currentPrinterNumber = 1;
}
notifyAll();
}
}
}
class Printer implements Runnable {
private Integer myInt;
private Manager myManager;
Integer getInt () {
return myInt;
}
public Printer (Integer i, Manager m) {
myInt = i;
myManager = m;
}
public void run () {
synchronized (myManager) {
while (true) {
try {
if (myManager.isMyTurn(this)) {
printMyInt();
}
myManager.wait();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
}
private void printMyInt () {
synchronized (myManager) {
System.out.print(myInt + " ");
myManager.complete();
}
}
}
import java.util.List;
import java.util.ArrayList;
public class Manager {
List<Thread> printers;
Integer currentPrinterNumber = 1;
public static void main (String[] args) throws Exception {
Manager aManager = new Manager();
aManager.initPrinters();
aManager.startPrinters();
}
public void initPrinters () {
printers = new ArrayList<Thread>();
for (int i = 1; i < 4; ++i) {
Printer p = new Printer(i, this);
Thread t = new Thread(p);
printers.add(t);
}
}
public void startPrinters () throws Exception {
for (Thread p : printers) {
p.start();
Thread.sleep(100);
}
}
public boolean isMyTurn (Printer p) {
if (p.getInt() == currentPrinterNumber) {
return true;
}
return false;
}
public void complete () {
synchronized (this) {
currentPrinterNumber++;
if (currentPrinterNumber > printers.size()) {
currentPrinterNumber = 1;
}
notifyAll();
}
}
}
class Printer implements Runnable {
private Integer myInt;
private Manager myManager;
Integer getInt () {
return myInt;
}
public Printer (Integer i, Manager m) {
myInt = i;
myManager = m;
}
public void run () {
synchronized (myManager) {
while (true) {
try {
if (myManager.isMyTurn(this)) {
printMyInt();
}
myManager.wait();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
}
private void printMyInt () {
synchronized (myManager) {
System.out.print(myInt + " ");
myManager.complete();
}
}
}
import java.util.concurrent.locks.*;
import java.util.*;
public class MultiThread{
private static final Lock lock = new ReentrantLock();
private static final Condition isAvailable = lock.newCondition();
private static List<Integer> validNos = Arrays.asList(1,2,3);
private static int roundRobbin = 1;
private static int getNextNumber(int number){
if(number < 3){
return number + 1;
}else{
return 1;
}
}
private static boolean isValid(final Integer number){
return validNos.contains(number);
}
public static Runnable getRunnable(final Integer number){
if(!isValid(number)){
throw new IllegalArgumentException("Please provide a valid input: " + number);
}
return new Runnable(){
public void run(){
while(true){
try{
lock.lock();
while(roundRobbin != number){
isAvailable.await();
}
System.out.println(number);
roundRobbin = getNextNumber(number);
isAvailable.signalAll();
}catch(Exception e){
System.err.println("Error acquiring lock for : " + number);
}finally{
lock.unlock();
}
}
}
};
}
public static void main(String[] args) {
Thread t1 = new Thread(getRunnable(1));
Thread t2 = new Thread(getRunnable(2));
Thread t3 = new Thread(getRunnable(3));
t1.start();
t2.start();
t3.start();
}
}
public class SyncThreads {
public static void main(String[] args) {
SharedObj obj = new SharedObj();
Thread t1 = new MyThread(1, 2, obj);
Thread t2 = new MyThread(2, 3, obj);
Thread t3 = new MyThread(3, 1, obj);
t1.start();
t2.start();
t3.start();
obj.setId(1);
synchronized (obj) {
obj.notifyAll();
}
}
}
class SharedObj {
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
class MyThread extends Thread {
int id;
int nextId;
SharedObj obj;
public MyThread(int id, int nextId, SharedObj obj) {
this.id = id;
this.nextId = nextId;
this.obj = obj;
}
public void run() {
while (true) {
while (obj.getId() != id)
try {
synchronized (obj) {
obj.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.print(" " + id);
obj.setId(nextId);
synchronized (obj) {
obj.notifyAll();
}
}
}
}
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
class WorkerThread implements Runnable {
private String command;
Semaphore s1 ;
Semaphore s2;
public WorkerThread(String s,Semaphore s1,Semaphore s2) {
this.command = s;
this.s1=s1;
this.s2=s2;
}
@Override
public void run() {
while (true) {
try {
s1.acquire();
System.out.println(command);
s2.release();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public class thread123 {
public static void main(String... args) {
Semaphore sem1 = new Semaphore(1);
Semaphore sem2 = new Semaphore(0);
Semaphore sem3 = new Semaphore(0);
ExecutorService executorService = Executors.newFixedThreadPool(10);
executorService.execute(new WorkerThread("1", sem1, sem2));
executorService.execute(new WorkerThread("2", sem2, sem3));
executorService.execute(new WorkerThread("3", sem3, sem1));
}
}
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
class WorkerThread implements Runnable {
private String command;
Semaphore s1 ;
Semaphore s2;
public WorkerThread(String s,Semaphore s1,Semaphore s2) {
this.command = s;
this.s1=s1;
this.s2=s2;
}
@Override
public void run() {
while (true) {
try {
s1.acquire();
System.out.println(command);
s2.release();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public class thread123 {
public static void main(String... args) {
Semaphore sem1 = new Semaphore(1);
Semaphore sem2 = new Semaphore(0);
Semaphore sem3 = new Semaphore(0);
ExecutorService executorService = Executors.newFixedThreadPool(10);
executorService.execute(new WorkerThread("1", sem1, sem2));
executorService.execute(new WorkerThread("2", sem2, sem3));
executorService.execute(new WorkerThread("3", sem3, sem1));
}
}
public class SequencePrint {
/**
* @Debanjan Ghosh
*/
Object monitor = new Object();
boolean one = true;
boolean two = false;
boolean three = false;
public static void main(String[] args) {
SequencePrint s = new SequencePrint();
Thread t1 = new Thread(s.new MyRunnable(1));
Thread t2 = new Thread(s.new MyRunnable(2));
Thread t3 = new Thread(s.new MyRunnable(3));
t1.start();
t2.start();
t3.start();
}
public class MyRunnable implements Runnable {
int threadId;
MyRunnable(int threadId) {
this.threadId = threadId;
}
@Override
public void run() {
print();
}
private void print() {
try {
while (true) {
Thread.sleep(101);
synchronized (monitor) {
if (1 == threadId) {
if (!one) {
monitor.wait();
} else {
System.out.println(threadId);
one = false;
two = true;
three = false;
monitor.notifyAll();
}
}
if (2 == threadId) {
if (!two) {
monitor.wait();
} else {
System.out.println(threadId);
one = false;
two = false;
three = true;
monitor.notifyAll();
}
}
if (3 == threadId) {
if (!three) {
monitor.wait();
} else {
System.out.println(threadId);
one = true;
two = false;
three = false;
monitor.notifyAll();
}
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class SequencePrint {
/**
* @Debanjan Ghosh
*/
Object monitor = new Object();
boolean one = true;
boolean two = false;
boolean three = false;
public static void main(String[] args) {
SequencePrint s = new SequencePrint();
Thread t1 = new Thread(s.new MyRunnable(1));
Thread t2 = new Thread(s.new MyRunnable(2));
Thread t3 = new Thread(s.new MyRunnable(3));
t1.start();
t2.start();
t3.start();
}
public class MyRunnable implements Runnable {
int threadId;
MyRunnable(int threadId) {
this.threadId = threadId;
}
@Override
public void run() {
print();
}
private void print() {
try {
while (true) {
Thread.sleep(101);
synchronized (monitor) {
if (1 == threadId) {
if (!one) {
monitor.wait();
} else {
System.out.println(threadId);
one = false;
two = true;
three = false;
monitor.notifyAll();
}
}
if (2 == threadId) {
if (!two) {
monitor.wait();
} else {
System.out.println(threadId);
one = false;
two = false;
three = true;
monitor.notifyAll();
}
}
if (3 == threadId) {
if (!three) {
monitor.wait();
} else {
System.out.println(threadId);
one = true;
two = false;
three = false;
monitor.notifyAll();
}
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
{public class SequencePrint {
/**
* @Debanjan Ghosh
*/
Object monitor = new Object();
boolean one = true;
boolean two = false;
boolean three = false;
public static void main(String[] args) {
SequencePrint s = new SequencePrint();
Thread t1 = new Thread(s.new MyRunnable(1));
Thread t2 = new Thread(s.new MyRunnable(2));
Thread t3 = new Thread(s.new MyRunnable(3));
t1.start();
t2.start();
t3.start();
}
public class MyRunnable implements Runnable {
int threadId;
MyRunnable(int threadId) {
this.threadId = threadId;
}
@Override
public void run() {
print();
}
private void print() {
try {
while (true) {
Thread.sleep(101);
synchronized (monitor) {
if (1 == threadId) {
if (!one) {
monitor.wait();
} else {
System.out.println(threadId);
one = false;
two = true;
three = false;
monitor.notifyAll();
}
}
if (2 == threadId) {
if (!two) {
monitor.wait();
} else {
System.out.println(threadId);
one = false;
two = false;
three = true;
monitor.notifyAll();
}
}
if (3 == threadId) {
if (!three) {
monitor.wait();
} else {
System.out.println(threadId);
one = true;
two = false;
three = false;
monitor.notifyAll();
}
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public class SequencePrint {
/**
* @Debanjan Ghosh
*/
Object monitor = new Object();
boolean one = true;
boolean two = false;
boolean three = false;
public static void main(String[] args) {
SequencePrint s = new SequencePrint();
Thread t1 = new Thread(s.new MyRunnable(1));
Thread t2 = new Thread(s.new MyRunnable(2));
Thread t3 = new Thread(s.new MyRunnable(3));
t1.start();
t2.start();
t3.start();
}
public class MyRunnable implements Runnable {
int threadId;
MyRunnable(int threadId) {
this.threadId = threadId;
}
@Override
public void run() {
print();
}
private void print() {
try {
while (true) {
Thread.sleep(101);
synchronized (monitor) {
if (1 == threadId) {
if (!one) {
monitor.wait();
} else {
System.out.println(threadId);
one = false;
two = true;
three = false;
monitor.notifyAll();
}
}
if (2 == threadId) {
if (!two) {
monitor.wait();
} else {
System.out.println(threadId);
one = false;
two = false;
three = true;
monitor.notifyAll();
}
}
if (3 == threadId) {
if (!three) {
monitor.wait();
} else {
System.out.println(threadId);
one = true;
two = false;
three = false;
monitor.notifyAll();
}
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class SequencePrint {
/**
* @Debanjan Ghosh
*/
Object monitor = new Object();
boolean one = true;
boolean two = false;
boolean three = false;
public static void main(String[] args) {
SequencePrint s = new SequencePrint();
Thread t1 = new Thread(s.new MyRunnable(1));
Thread t2 = new Thread(s.new MyRunnable(2));
Thread t3 = new Thread(s.new MyRunnable(3));
t1.start();
t2.start();
t3.start();
}
public class MyRunnable implements Runnable {
int threadId;
MyRunnable(int threadId) {
this.threadId = threadId;
}
@Override
public void run() {
print();
}
private void print() {
try {
while (true) {
Thread.sleep(101);
synchronized (monitor) {
if (1 == threadId) {
if (!one) {
monitor.wait();
} else {
System.out.println(threadId);
one = false;
two = true;
three = false;
monitor.notifyAll();
}
}
if (2 == threadId) {
if (!two) {
monitor.wait();
} else {
System.out.println(threadId);
one = false;
two = false;
three = true;
monitor.notifyAll();
}
}
if (3 == threadId) {
if (!three) {
monitor.wait();
} else {
System.out.println(threadId);
one = true;
two = false;
three = false;
monitor.notifyAll();
}
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
using namespace std;
class Printer {
private:
static mutex printerMutex;
static condition_variable printerCondition;
static int currentPrintingNumber;
public:
void unorderedPrint(int x) {
for (int i = 0; i < 10; ++i) {
cout << x;
this_thread::sleep_for(chrono::milliseconds(100));
}
}
void orderedPrint(int x, int max) {
for (int i = 0; i < 10; ++i) {
unique_lock<mutex> locker(printerMutex);
while (currentPrintingNumber != x - 1)
printerCondition.wait(locker);
cout << x;
currentPrintingNumber = x % max;
printerCondition.notify_all();
this_thread::sleep_for(chrono::milliseconds(100));
}
}
};
mutex Printer::printerMutex;
condition_variable Printer::printerCondition;
int Printer::currentPrintingNumber;
void main() {
Printer printer;
thread unorderedPrint1(&Printer::unorderedPrint, &printer, 1);
thread unorderedPrint2(&Printer::unorderedPrint, &printer, 2);
thread unorderedPrint3(&Printer::unorderedPrint, &printer, 3);
unorderedPrint1.join();
unorderedPrint2.join();
unorderedPrint3.join();
cout << endl;
thread orderedPrint1(&Printer::orderedPrint, &printer, 1, 3);
thread orderedPrint2(&Printer::orderedPrint, &printer, 2, 3);
thread orderedPrint3(&Printer::orderedPrint, &printer, 3, 3);
orderedPrint1.join();
orderedPrint2.join();
orderedPrint3.join();
cout << endl;
system("pause");
}
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
using namespace std;
class Printer {
private:
static mutex printerMutex;
static condition_variable printerCondition;
static int currentPrintingNumber;
public:
void unorderedPrint(int x) {
for (int i = 0; i < 10; ++i) {
cout << x;
this_thread::sleep_for(chrono::milliseconds(100));
}
}
void orderedPrint(int x, int max) {
for (int i = 0; i < 10; ++i) {
unique_lock<mutex> locker(printerMutex);
while (currentPrintingNumber != x - 1)
printerCondition.wait(locker);
cout << x;
currentPrintingNumber = x % max;
printerCondition.notify_all();
this_thread::sleep_for(chrono::milliseconds(100));
}
}
};
mutex Printer::printerMutex;
condition_variable Printer::printerCondition;
int Printer::currentPrintingNumber;
void main() {
Printer printer;
thread unorderedPrint1(&Printer::unorderedPrint, &printer, 1);
thread unorderedPrint2(&Printer::unorderedPrint, &printer, 2);
thread unorderedPrint3(&Printer::unorderedPrint, &printer, 3);
unorderedPrint1.join();
unorderedPrint2.join();
unorderedPrint3.join();
cout << endl;
thread orderedPrint1(&Printer::orderedPrint, &printer, 1, 3);
thread orderedPrint2(&Printer::orderedPrint, &printer, 2, 3);
thread orderedPrint3(&Printer::orderedPrint, &printer, 3, 3);
orderedPrint1.join();
orderedPrint2.join();
orderedPrint3.join();
cout << endl;
system("pause");
}
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
using namespace std;
class Printer {
private:
static mutex printerMutex;
static condition_variable printerCondition;
static int currentPrintingNumber;
public:
void unorderedPrint(int x) {
for (int i = 0; i < 10; ++i) {
cout << x;
this_thread::sleep_for(chrono::milliseconds(100));
}
}
void orderedPrint(int x, int max) {
for (int i = 0; i < 10; ++i) {
unique_lock<mutex> locker(printerMutex);
while (currentPrintingNumber != x - 1)
printerCondition.wait(locker);
cout << x;
currentPrintingNumber = x % max;
printerCondition.notify_all();
this_thread::sleep_for(chrono::milliseconds(100));
}
}
};
mutex Printer::printerMutex;
condition_variable Printer::printerCondition;
int Printer::currentPrintingNumber;
void main() {
Printer printer;
thread unorderedPrint1(&Printer::unorderedPrint, &printer, 1);
thread unorderedPrint2(&Printer::unorderedPrint, &printer, 2);
thread unorderedPrint3(&Printer::unorderedPrint, &printer, 3);
unorderedPrint1.join();
unorderedPrint2.join();
unorderedPrint3.join();
cout << endl;
thread orderedPrint1(&Printer::orderedPrint, &printer, 1, 3);
thread orderedPrint2(&Printer::orderedPrint, &printer, 2, 3);
thread orderedPrint3(&Printer::orderedPrint, &printer, 3, 3);
orderedPrint1.join();
orderedPrint2.join();
orderedPrint3.join();
cout << endl;
system("pause");
}
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
using namespace std;
class Printer {
private:
static mutex printerMutex;
static condition_variable printerCondition;
static int currentPrintingNumber;
public:
void unorderedPrint(int x) {
for (int i = 0; i < 10; ++i) {
cout << x;
this_thread::sleep_for(chrono::milliseconds(100));
}
}
void orderedPrint(int x, int max) {
for (int i = 0; i < 10; ++i) {
unique_lock<mutex> locker(printerMutex);
while (currentPrintingNumber != x - 1)
printerCondition.wait(locker);
cout << x;
currentPrintingNumber = x % max;
printerCondition.notify_all();
this_thread::sleep_for(chrono::milliseconds(100));
}
}
};
mutex Printer::printerMutex;
condition_variable Printer::printerCondition;
int Printer::currentPrintingNumber;
void main() {
Printer printer;
thread unorderedPrint1(&Printer::unorderedPrint, &printer, 1);
thread unorderedPrint2(&Printer::unorderedPrint, &printer, 2);
thread unorderedPrint3(&Printer::unorderedPrint, &printer, 3);
unorderedPrint1.join();
unorderedPrint2.join();
unorderedPrint3.join();
cout << endl;
thread orderedPrint1(&Printer::orderedPrint, &printer, 1, 3);
thread orderedPrint2(&Printer::orderedPrint, &printer, 2, 3);
thread orderedPrint3(&Printer::orderedPrint, &printer, 3, 3);
orderedPrint1.join();
orderedPrint2.join();
orderedPrint3.join();
cout << endl;
system("pause");
}
import java.util.concurrent.Semaphore;
public class SnowflakeInterview {
public static void main(String[] args) {
Printer printer = new Printer();
Counter c1 = new Counter(1, printer);
Counter c2 = new Counter(2, printer);
Counter c3 = new Counter(3, printer);
c1.toNotify = c2;
c2.toNotify = c3;
c3.toNotify = c1;
c1.start();
c2.start();
c3.start();
}
}
class Printer {
private int turn = 1;
public synchronized void print(int id, int next) {
while (turn != id) {
try {
wait();
} catch (InterruptedException e) { }
}
System.out.println(id);
turn = next;
notifyAll();
}
}
class Counter extends Thread {
private int id;
Counter toNotify;
private Printer printer;
public Counter(int id, Printer printer) {
this.id = id;
this.printer = printer;
}
@Override
public void run() {
int i = 0;
while (true) {
this.printer.print(this.id, this.toNotify.id);
}
}
}
import java.util.concurrent.Semaphore;
public class SnowflakeInterview {
public static void main(String[] args) {
Printer printer = new Printer();
Counter c1 = new Counter(1, printer);
Counter c2 = new Counter(2, printer);
Counter c3 = new Counter(3, printer);
c1.toNotify = c2;
c2.toNotify = c3;
c3.toNotify = c1;
c1.start();
c2.start();
c3.start();
}
}
class Printer {
private int turn = 1;
public synchronized void print(int id, int next) {
while (turn != id) {
try {
wait();
} catch (InterruptedException e) { }
}
System.out.println(id);
turn = next;
notifyAll();
}
}
class Counter extends Thread {
private int id;
Counter toNotify;
private Printer printer;
public Counter(int id, Printer printer) {
this.id = id;
this.printer = printer;
}
@Override
public void run() {
int i = 0;
while (true) {
this.printer.print(this.id, this.toNotify.id);
}
}
}
import java.util.concurrent.Semaphore;
public class SnowflakeInterview {
public static void main(String[] args) {
Printer printer = new Printer();
Counter c1 = new Counter(1, printer);
Counter c2 = new Counter(2, printer);
Counter c3 = new Counter(3, printer);
c1.toNotify = c2;
c2.toNotify = c3;
c3.toNotify = c1;
c1.start();
c2.start();
c3.start();
}
}
class Printer {
private int turn = 1;
public synchronized void print(int id, int next) {
while (turn != id) {
try {
wait();
} catch (InterruptedException e) { }
}
System.out.println(id);
turn = next;
notifyAll();
}
}
class Counter extends Thread {
private int id;
Counter toNotify;
private Printer printer;
public Counter(int id, Printer printer) {
this.id = id;
this.printer = printer;
}
@Override
public void run() {
int i = 0;
while (true) {
this.printer.print(this.id, this.toNotify.id);
}
}
}
public class MyClass {
public static void main(String[] args) {
Printer printer = new Printer();
Counter c1 = new Counter(1, printer);
Counter c2 = new Counter(2, printer);
Counter c3 = new Counter(3, printer);
c1.toNotify = c2;
c2.toNotify = c3;
c3.toNotify = c1;
c1.start();
c2.start();
c3.start();
}
}
class Printer {
private int turn = 1;
public synchronized void print(int id, int next) {
while (turn != id) {
try {
wait();
} catch (InterruptedException e) { }
}
System.out.println(id);
turn = next;
notifyAll();
}
}
class Counter extends Thread {
private int id;
Counter toNotify;
private Printer printer;
public Counter(int id, Printer printer) {
this.id = id;
this.printer = printer;
}
@Override
public void run() {
int i = 0;
while (true) {
this.printer.print(this.id, this.toNotify.id);
}
}
}
This problem can be implemented simply with help of interrupt.Each thread should know which next thread to implement
package ContinuousThreading;
import java.util.*;
import myThreads.PrintingThread;
/**
* Hello world!
*
*/
public class App
{
public static void main( String[] args )
{
System.out.println( "Hello World!" );
int NoOfThread = 5;
App theApp = new App();
List<PrintingThread> listOfThreads = new ArrayList<PrintingThread>();
theApp.initializeThreads(NoOfThread,listOfThreads);
theApp.startThreads(NoOfThread,listOfThreads);
}
private void startThreads(int iNoOfThreads,List<PrintingThread> iListOfThreads)
{
for(int i = 1; i <= iNoOfThreads; i++)
{
(iListOfThreads.get( i - 1 ) ).start();
}
}
private void makeThreadsInterruptable(int iNoOfThreads,List<PrintingThread> iListOfThreads)
{
for(int i = 1; i <= iNoOfThreads; i++)
{
if( i == iNoOfThreads)
(iListOfThreads.get( iNoOfThreads - 1 ) ).setThreadToInterrupt( iListOfThreads.get( 0 ) );
else
(iListOfThreads.get( i - 1 ) ).setThreadToInterrupt( iListOfThreads.get( i ) );
}
}
private void initializeThreads(int iNoOfThreads,List<PrintingThread> iListOfThreads)
{
for(int i = 1; i <= iNoOfThreads; i++)
{
iListOfThreads.add( new PrintingThread( i ) ) ;
}
makeThreadsInterruptable(iNoOfThreads,iListOfThreads);
}
}
package myThreads;
public class PrintingThread extends Thread{
int StartNum;
Thread threadToInterrupt;
public PrintingThread(int StartNum)
{
this.StartNum = StartNum;
}
public void setThreadToInterrupt(Thread iThreadToInterrupt)
{
threadToInterrupt = iThreadToInterrupt;
}
public void run()
{
int i = 1;
while(i < 100 )
{
if( (StartNum == 1) && (i == 1) )
{
System.out.print(StartNum);
threadToInterrupt.interrupt();
}
while(!isInterrupted())
{
try{sleep(5);}
catch(InterruptedException e)
{
System.out.print(StartNum);
threadToInterrupt.interrupt();
}
}
i++;
}
}
}
#include <iostream>
#include <thread>
std::mutex m;
std::condition_variable cv;
int cnt = 1;
void f(int id) {
for (;;) {
std::unique_lock<std::mutex> lk(m);
cv.wait(lk, [&]() {return cnt%3==id-1;});
std::cout<<id<<"\n";
cnt++;
cv.notify_all();
}
}
int main() {
std::thread t1(f,1), t2(f,2), t3(f,3);
t1.join(); t2.join(); t3.join();
return 0;
}
Simple C++ solution:
#include <iostream>
#include <thread>
std::mutex m;
std::condition_variable cv;
int cnt = 1;
void f(int id) {
for (;;) {
std::unique_lock<std::mutex> lk(m);
cv.wait(lk, [&]() {return cnt%3==id-1;});
std::cout<<id<<"\n";
cnt++;
cv.notify_all();
}
}
int main() {
std::thread t1(f,1), t2(f,2), t3(f,3);
t1.join(); t2.join(); t3.join();
return 0;
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
Semaphore.PrintNumbers();
Console.ReadKey();
}
}
public class Semaphore
{
static SemaphoreSlim sema = new SemaphoreSlim(1, 1);
static LinkedList<int> Numbers = new LinkedList<int>();
private static Thread th1;
private static Thread th2;
private static Thread th3;
private static void PrintOne()
{
while (Numbers.Count >0) {
sema.Wait();
var a = Numbers.FirstOrDefault();
if (a == 1) {
Console.WriteLine(1);
Numbers.RemoveFirst();
}
sema.Release();
}
}
private static void PrintSecond() {
while (Numbers.Count > 0) {
sema.Wait();
var a = Numbers.FirstOrDefault();
if (a == 2) {
Console.WriteLine(a);
Numbers.RemoveFirst();
}
sema.Release();
}
}
private static void PrintThird()
{
while (Numbers.Count > 0) {
sema.Wait();
var a = Numbers.FirstOrDefault();
if (a == 3)
{
Console.WriteLine(a);
Numbers.RemoveFirst();
}
sema.Release();
}
}
public static void PrintNumbers() {
Numbers.AddLast(1);
Numbers.AddLast(2);
Numbers.AddLast(3);
Numbers.AddLast(1);
Numbers.AddLast(2);
Numbers.AddLast(3);
Numbers.AddLast(1);
Numbers.AddLast(2);
Numbers.AddLast(3);
th1 = new Thread(PrintOne);
th2 = new Thread(PrintSecond);
th3 = new Thread(PrintThird);
th1.Name = "first";
th2.Name = "second";
th3.Name = "third";
th1.Start();
th2.Start();
th3.Start();
th1.Join();
th2.Join();
th3.Join();
}
}
}
class Mutex{}
class MyThread extends Thread{
private int val;
private Mutex wMutex, nMutex;
public MyThread(int i, Mutex waitMutex, Mutex notifMutex){
val = i;
wMutex = waitMutex;
nMutex = notifMutex;
}
@Override
public void run() {
while (true){
System.out.println(val);
synchronized(nMutex){ nMutex.notify(); } //invoke next thread
synchronized(wMutex){ //wait for current mutex
try { wMutex.wait(); }
catch (InterruptedException e) { }
}
}
}
}
public class ThreadNotifyDemo {
public static void main(String[] Args){
Mutex m1 = new Mutex(), m2 = new Mutex(), m3 = new Mutex();
MyThread t1 = new MyThread(1, m1, m2);
MyThread t2 = new MyThread(2, m2, m3);
MyThread t3 = new MyThread(3, m3, m1);
t1.start();
t2.start();
t3.start();
}
}
package cup.salesforce;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class PrintSequence {
public static void main(String[] args) {
Printer printer = new Printer();
PrinterThread one = new PrinterThread(printer, 1);
PrinterThread two = new PrinterThread(printer, 2);
PrinterThread three = new PrinterThread(printer, 3);
one.start();
two.start();
three.start();
}
static class Printer{
int prevId;
Lock lock = new ReentrantLock();
Condition[] conditions = {lock.newCondition(), lock.newCondition(), lock.newCondition()};
public Printer(){
this.prevId = 0;
}
public void print(int id){
lock.lock();
try{
if(prevId!=id-1)conditions[id-1].await();
System.out.println(" " + id);
int nxtId = id > 2 ? 0:id;
this.prevId = id;
conditions[nxtId].signal();
}catch(InterruptedException e){
e.printStackTrace();
}finally{
lock.unlock();
}
}
}
static class PrinterThread extends Thread implements Runnable{
Printer printer;
int id;
public PrinterThread(Printer printer, int id){
this.printer = printer;
this.id = id;
}
public void run(){
while(true) printer.print(this.id);
}
}
}
Can anyone verify this code?
It is correct??
#include "pch.h"
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
using namespace std;
condition_variable c1, c2;
mutex m1, m2;
void function_1() {
while (1) {
unique_lock<mutex> l(m1);
c1.wait(l);
cout << 1;
this_thread::sleep_for(chrono::seconds(1));
c2.notify_one();
}
}
void function_2() {
while (1) {
unique_lock<mutex> l(m2);
c2.wait(l);
cout << 2;
this_thread::sleep_for(chrono::seconds(1));
c1.notify_one();
}
}
int main() {
thread t1(function_1);
thread t2(function_2);
c1.notify_one();
t1.join();
t2.join();
return 0;
}
Try creating a class that implements Runnable that outputs the number then sleeps, giving other threads enough time to output their number. Running them in order will then give you your result. Is that what you were looking for?
public void thread123() {
MyThread thread1 = new MyThread(1);
MyThread thread2 = new MyThread(2);
MyThread thread3 = new MyThread(3);
while (true) {
thread1.run();
thread2.run();
thread3.run();
}
}
class MyThread implements Runnable {
int data = 0;
public MyThread(int data) {
this.data = data;
}
public void run() {
System.out.print(data + " ");
try {
Thread.sleep(1000);
}
catch (Exception e) {
e.printStackTrace();
}
}
}
MyThread is runnable.
So to start a thread you must pass this object to a thread constructor and then call start() method of the thread. So it's not multithreading, what you are are doing.
You are running a single threaded program. It's not the answer.
Main class
public class Main {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Synchronizer sync = Synchronizer.getInstance();
ObjRunnable objRunnable = new ObjRunnable(sync);
Thread t1 = new Thread(objRunnable,"1");
Thread t2 = new Thread(objRunnable,"2");
Thread t3 = new Thread(objRunnable,"3");
t3.start();
t1.start();
t2.start();
}
}
Singleton Synchronizer class
public class Synchronizer {
private static final Synchronizer sync = new Synchronizer();
private int nowAccessedBy ;//1 means first thread
private String quit;
private Synchronizer(){
nowAccessedBy = 1;
quit = null;
}
public synchronized void maintainOrder(){
String threadName;
while(quit==null){
threadName = Thread.currentThread().getName();
if(threadName.equals("1")&& nowAccessedBy == 1){
nowAccessedBy = 2;
System.out.println(threadName);
notifyOthers();
}else if(threadName.equals("2")&& nowAccessedBy == 2){
nowAccessedBy = 3;
System.out.println(threadName);
notifyOthers();
}else if(threadName.equals("3")&& nowAccessedBy == 3){
nowAccessedBy = 1;
System.out.println(threadName);
notifyOthers();
}else{
notifyOthers();
}
}
}
private void notifyOthers(){
notifyAll();
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static Synchronizer getInstance(){
return sync;
}
}
ObjRunnable class
public class ObjRunnable implements Runnable {
private final Synchronizer lock;
public ObjRunnable(Synchronizer lock) {
this.lock = lock;
}
@Override
public void run() {
lock.maintainOrder();
}
}
- Crystal January 26, 2016