If i know a specific thread id. How to do the following?
Thread.getThreadById(id).continueWork();
Is it possible?
public class Test implements Runnable {
public void run() {
while(true){
pause();
doSomework();
}
}
private void doSomework() {
System.out.println("do some work");
}
public synchronized void pause() {
if (Tester.waitCondition == true) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public synchronized void continueWork() {
notify();
}
}
public class Tester {
public static boolean waitCondition = true;
public static void main(String[] args) {
Thread nThread = new Thread(new Test());
nThread.start();
waitCondition = false;
Thread nThread1 = new Thread(new Test());
nThread1.start();
Thread nThread2 = new Thread(new Test());
nThread2.start();
Thread nThread3 = new Thread(new Test());
nThread3.start();
Long id = nThread.getId();
Thread.getThreadById(id).continueWork();
}
}
You need block the thread with a lock , then call the lock's notify method to set blocked thread runnable .
If more than one thread to be continued , you will need Condition .
Like blow:
final Lock lock = new ReentrantLock();
final Condition condition1 = lock.newCondition();
final Condition condition2 = lock.newCondition();
Thread t = new Thread() {
#Override
public void run() {
try {
lock.lock();
condition1.await();
System.out.println("end cdt1");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
lock.unlock();
}
}
};
t.start();
Thread t1 = new Thread() {
#Override
public void run() {
try {
lock.lock();
condition2.await();
System.out.println("end cdt2");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
lock.unlock();
}
}
};
t1.start();
Thread.sleep(1000);
Thread tt = new Thread() {
#Override
public void run() {
try {
lock.lock();
condition1.signal();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
lock.unlock();
}
}
};
tt.start();
Thread.sleep(2000);
Thread tt1 = new Thread() {
#Override
public void run() {
try {
lock.lock();
condition2.signal();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
lock.unlock();
}
}
};
tt1.start();
Elaborating:
public class Tester {
// Apologies, I'm too lazy to create two separate files
static public class Test implements Runnable {
private void doSomework() {
System.out.print(
"do some work on Thread: "
+Thread.currentThread().getId()
);
try {
Thread.sleep(500); // just to simulate a load
}
catch(InterruptedException e) {
// ignore
}
}
public void run() {
do {
boolean shouldIWait=true;
synchronized(Tester.lockingObj) {
Boolean flag=Tester.waitConditions.get(Thread.currentThread().getId());
if(null!=flag) {
shouldIWait=flag.booleanValue();
} // if null, the tester started me before creating my flag. I'll wait
if(shouldIWait) {
// I need to wait for someone to wake me
try {
Tester.lockingObj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
// well, I'm interrupted, so I'll do no more work.
break;
}
}
}
if(false==shouldIWait) {
// waiting no more
this.doSomework();
}
} while(true);
}
}
public static Object lockingObj=new Object();
public static TreeMap<Long, Boolean> waitConditions=
new TreeMap<Long, Boolean>();
public static void main(String[] args) {
Thread nThread = new Thread(new Test());
Thread nThread1 = new Thread(new Test());
Thread nThread2 = new Thread(new Test());
Thread nThread3 = new Thread(new Test());
// when starting, all threads will be waiting
waitConditions.put(nThread.getId(), true);
waitConditions.put(nThread.getId(), true);
waitConditions.put(nThread.getId(), true);
waitConditions.put(nThread.getId(), true);
nThread2.start();
nThread1.start();
nThread.start();
nThread3.start();
Long id = nThread.getId();
synchronized (lockingObj) { // when notified, all thread should wakeup
waitConditions.put(id, false); // but only nThread will be allowed to doSomeWork
lockingObj.notifyAll(); // wake up all the threads.
// Those not allowed, will go into
// back waiting
}
try {
// just to have the main thread still running for a while
Thread.sleep(3000);
} catch (InterruptedException e) {
}
// maybe we want to switch of nThread and start another?
synchronized (lockingObj) {
waitConditions.put(id, true);
waitConditions.put(nThread1.getId(), false);
lockingObj.notifyAll();
}
try {
// just to have the main thread still running for a while
Thread.sleep(3000);
} catch (InterruptedException e) {
}
}
}
Related
I am unable to understand why the code mentioned in the listing 8.3 in the book is not deadlock prone. When I run the code, it doesn't leads to deadlock. I took the idea from the book and modified the code.
Below is the program:-
public class LockOrderingDeadLockSolved {
private final Object left = new Object();
private final Object right = new Object();
private final Object tieLock = new Object();
public static void main(String[] args) {
LockOrderingDeadLockSolved obj = new LockOrderingDeadLockSolved();
int leftHash = System.identityHashCode(obj.left);
int rightHash = System.identityHashCode(obj.right);
System.out.println(leftHash +" --- " + rightHash);
Thread t = new Thread() {
public void run() {
if (leftHash < rightHash)
obj.leftRight();
else if (leftHash > rightHash)
obj.rightLeft();
else
obj.tieLockMethod();
}
};
Thread t1 = new Thread() {
public void run() {
if (leftHash < rightHash)
obj.leftRight();
else if (leftHash > rightHash)
obj.rightLeft();
else
obj.tieLockMethod();
}
};
t.start();
t1.start();
}
private void leftRight() {
synchronized (left) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized (right) {
System.out.println("Left right -- left right lock");
}
}
}
private void rightLeft() {
synchronized (right) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized (left) {
System.out.println("Right left -- right left lock");
}
}
}
private void tieLockMethod() {
synchronized (tieLock) {
synchronized (left) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized (right) {
System.out.println("Right left --- tie lock");
}
}
}
}
}
Output:-
865113938 --- 1442407170
Left right -- left right lock
Left right -- left right lock
Deadlock prone program:-
public class LockOrderingDeadLock {
private final Object left = new Object();
private final Object right = new Object();
public static void main(String[] args) {
LockOrderingDeadLock obj = new LockOrderingDeadLock();
Thread t = new Thread() {
public void run() {
obj.leftRight();
}
};
Thread t1 = new Thread() {
public void run() {
obj.rightLeft();
}
};
t.start();
t1.start();
}
private void leftRight() {
synchronized (left) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized (right) {
System.out.println("Left right");
}
}
}
private void rightLeft() {
synchronized (right) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized (left) {
System.out.println("Right left");
}
}
}
}
If the locks are acquired in the same order the deadlock won't happen.
To make your example deadlock you have to repeatedly acquire the same locks in a different order. This can be done with the following code.
private static final Object left = new Object();
private static final Object right = new Object();
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
while (true) {
synchronized (left) {
synchronized (right) {
System.out.println("Left right -- left right lock");
}
}
}
});
Thread t2 = new Thread(() -> {
while (true) {
synchronized (right) {
synchronized (left) {
System.out.println("Right left -- right left lock");
}
}
}
});
t1.start();
t2.start();
}
I need to run 2 threads simultaneously (on occasion if both have been requested together) otherwise if either one is requested solo then each thread needs to run on its own. Each thread will be responsible for taking its own unique reading from its own unique transducer (actual hardware), I need each thread to query its transducer until a certain value is detected. If and only if this value is detected should the thread stop and exit.
I also need a way for my software to know without a doubt that both threads have stopped and exited/completed their task and detected their respective values from the hardware. If and only if both threads detect their values should my onFinish() method be called. In my code, I used a third thread to do this monitoring and the use of integer values. The integer variable threadCount is reset to 0 once my onFinish() method is called and so is my boolean shouldRun which is reset to false within the onFinish() method.
Was wondering if my approach is acceptable/sound logically ( please note I havent done the logic yet for the actual query of each transducer (likely will use a while loop)) also what are the consequences for using the approach I described, my code is as seen below:
private void decreaseThreadCount(){
threadCount -=1;
}
boolean shouldRun = false;
int threadCount = 0;
public void onStart() {
System.out.println("START");
System.out.println(" ");
System.out.println("START PROGRESS BAR");
if((customProgressBarL != null || customProgressBarR != null) || (customProgressBarL != null && customProgressBarR != null)){
shouldRun = true;
}
/**TESTING PURPOSES*/
if (customProgressBarL != null) {
threadCount += 1;
new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i <= 100; i++) {
try {
customProgressBarL.updateProgress(i);
customProgressBarL.repaint();
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(5);
decreaseThreadCount();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
if (customProgressBarR != null) {
threadCount += 1;
new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i <= 100; i++) {
try {
customProgressBarR.updateProgress(i);
customProgressBarR.repaint();
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//System.out.println("Thread Count: " + threadCount);
try {
Thread.sleep(5);
decreaseThreadCount();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
new Thread(new Runnable() {
#Override
public void run() {
while(threadCount >= 0 && shouldRun){
try {
System.out.println("Thread Count: " + threadCount);
if(threadCount == 0){
onFinish();
return;
}
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return;
}
}).start();
}
[Edit 1] After reading through the advice given and a bunch of online documentation I have come up with the following code which seems to work under the cases I have tested so far.
Was wondering if I should still use SwingWorkers or if the modified approach is acceptable?
public void onStart() {
System.out.println("START");
System.out.println(" ");
System.out.println("START PROGRESS BAR");
/**TESTING PURPOSES*/
CountDownLatch countDownLatch = new CountDownLatch(2);
new Thread(new Runnable() {
#Override
public void run() {
new Thread(new Runnable() {
#Override
public void run() {
if (customProgressBarL != null) {
for (int i = 0; i <= 100; i++) {
try {
customProgressBarL.updateProgress(i);
customProgressBarL.repaint();
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
countDownLatch.countDown();
return;
}
}).start();
new Thread(new Runnable() {
#Override
public void run() {
if(customProgressBarR != null){
for (int i = 0; i <= 100; i++) {
try {
customProgressBarR.updateProgress(i);
customProgressBarR.repaint();
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
countDownLatch.countDown();
return;
}
}).start();
try{
countDownLatch.await();
onFinish();
} catch (InterruptedException e){
e.printStackTrace();
}
}
}).start();
}
[Edit 2]
I have tried a version where I use SwingWorker instead of my Threads, below is the code and it works just as well as the code in [Edit 1] (as far as I can tell at least). What are the pros/cons of each approach?
private class MySwingWorker extends SwingWorker<Object, Object> {
CountDownLatch countDownLatch;
JCustomProgressBar progressBar;
public MySwingWorker(CountDownLatch countDownLatch, JCustomProgressBar progressBar){
this.countDownLatch = countDownLatch;
this.progressBar = progressBar;
}
#Override
protected Object doInBackground() throws Exception {
if(progressBar != null){
for (int i = 0; i <= 100; i++) {
try {
progressBar.updateProgress(i);
progressBar.repaint();
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
countDownLatch.countDown();
return null;
}
}
private class MySwingWorkerManager extends SwingWorker<Object, Object> {
CountDownLatch countDownLatch;
#Override
protected Object doInBackground() throws Exception {
this.countDownLatch = new CountDownLatch(2);
new MySwingWorker(countDownLatch, customProgressBarL).execute();
new MySwingWorker(countDownLatch, customProgressBarR).execute();
try{
countDownLatch.await();
onFinish();
} catch (InterruptedException e){
e.printStackTrace();
}
return null;
}
}
I initiate everything as follows in my onStart() method by calling the execute() method:
public void onStart() {
System.out.println("START");
System.out.println(" ");
System.out.println("START PROGRESS BAR");
System.out.println("customProgressBarL is: "+customProgressBarL);
System.out.println("customProgressBarR is: "+customProgressBarR);
/**TESTING PURPOSES*/
new MySwingWorkerManager().execute();
}
You've initiated all the threads simultanesouly outside (T1,T2,T3) and T3 is waiting for all of them to finish and do some onFinish.
Instead you can instantiate T1 and T2 inside T3.
Create a countdown latch with the number of count.
Decrement the latch count when both the threads finish their task and then execute onFinish().
All the logic to create T1/T2 should be inside T3.
new Thread(new Runnable() {
#Override
public void run() {
int count = 2;
CountdownLatch latch = new CountdownLatch(count);
MyThread t1 = new MyThread(latch);
MyThread t2 = new MyThread(latch);
t1.start()
t2.start();
latch.await();
onFinish();
}
}).start();
Only one thread is supposed to access swing components; you should write something like that:
SwingUtilities.invokeLater(() -> {
customProgressBarR.updateProgress(i);
customProgressBarR.repaint();
});
I am trying to write a program with two Java threads. One shall print odd and the other shall print even numbers. The output should be in sequence. My code is not working properly. Please correct it and tell me what was the error.
public class App {
public static void main(String[] args) {
ThrdO to=new ThrdO();
Thread t1=new Thread(to);
ThredE te=new ThredE();
Thread t2=new Thread(te);
t1.start();
t2.start();
}
}
public class ThrdO implements Runnable{
PrintCl pcl =new PrintCl();
#Override
public void run() {
for(int i=0;i<10;i+=2)
pcl.Even(i);
}
}
public class ThredE implements Runnable {
PrintCl pcl =new PrintCl();
#Override
public void run() {
for(int i=1;i<10;i+=2)
try {
pcl.odd(i);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public class PrintCl {
public void Even(int n) {
synchronized (this) {
System.out.println(n);
this.notifyAll();
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void odd(int n) throws InterruptedException {
synchronized (this) {
System.out.println(n);
this.notifyAll();
this.wait();
}
}
}
getting output
0 ,1
This is a much cleaner way of achieving what you want, without ugly sleeps in the code, not to mention that it will run faster than code with a sleep in it, for obvious reasons.
public class App {
public static void main(String[] args) {
PrintCl pcl = new PrintCl();
Thread t1 = new Thread(new ThrdEven(pcl));
Thread t2 = new Thread(new ThrdOdd(pcl));
t1.start();
t2.start();
}
}
public class ThrdEven implements Runnable {
private PrintCl pcl = null;
public ThrdEven(PrintCl pcl) {
this.pcl = pcl;
}
#Override
public void run() {
for (int i = 0; i < 10; i += 2) {
pcl.Even(i);
}
}
}
public class ThrdOdd implements Runnable {
private PrintCl pcl = null;
public ThrdOdd(PrintCl pcl) {
this.pcl = pcl;
}
#Override
public void run() {
for (int i = 1; i < 10; i += 2) {
pcl.odd(i);
}
}
}
public class PrintCl {
private final Object _lock = new Object();
private boolean isEvenAllowed = true;
public void Even(int n) {
synchronized (this._lock) {
while (!this.isEvenAllowed) {
try {
this._lock.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
throw new RuntimeException(e);
}
}
System.out.println(n);
this.isEvenAllowed = false;
this._lock.notifyAll();
}
}
public void odd(int n) {
synchronized (this._lock) {
while (this.isEvenAllowed) {
try {
this._lock.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
throw new RuntimeException(e);
}
}
System.out.println(n);
this.isEvenAllowed = true;
this._lock.notifyAll();
}
}
}
Please try following changes in your code:
public class App {
public static void main(String[] args) throws InterruptedException {
PrintCl pcl =new PrintCl();
ThrdO to=new ThrdO();
to.setPcl(pcl);
Thread t1=new Thread(to);
ThredE te=new ThredE();
te.setPcl(pcl);
Thread t2=new Thread(te);
t1.start();
Thread.sleep(1000);
t2.start();
}
}
And for Thrd0:
public class ThrdO implements Runnable {
PrintCl pcl =null;
#Override
public void run() {
for(int i=0;i<10;i+=2)
pcl.Even(i);
}
public PrintCl getPcl() {
return pcl;
}
public void setPcl(PrintCl pcl) {
this.pcl = pcl;
}
}
ThredE:
public class ThredE implements Runnable {
PrintCl pcl =null;
#Override
public void run() {
for(int i=1;i<10;i+=2)
try {
pcl.odd(i);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public PrintCl getPcl() {
return pcl;
}
public void setPcl(PrintCl pcl) {
this.pcl = pcl;
}
}
Your code has two basic problems
Every thread have its own printing resource . Hence once printing their first number they are waiting for notification endlessly.
Once you will fix this issue , Another issue is your one thread will be finished but second thread would still be waiting for its notification and it will never die.
I have fixed both issues in below code
public class Test {
public static void main(String[] args) throws InterruptedException {
PrintCl pcl =new PrintCl();
ThrdO to=new ThrdO(pcl);
Thread t1=new Thread(to);
ThredE te=new ThredE(pcl);
Thread t2=new Thread(te);
t1.start();
Thread.sleep(1000);// just to ensure that T1 should start first
t2.start();
}
}
class ThrdO implements Runnable{
private PrintCl pcl;
public ThrdO(PrintCl pcl) {
this.pcl = pcl;
}
#Override
public void run() {
for(int i=0;i<10;i+=2) {
try {
pcl.Even(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized (pcl){
System.out.println("Releasing lock on pcl");
pcl.notify();
}
System.out.println("ThrdO has finished its working");
}
}
class ThredE implements Runnable {
PrintCl pcl ;
public ThredE(PrintCl pcl) {
this.pcl = pcl;
}
#Override
public void run() {
for (int i = 1; i < 10; i += 2) {
try {
pcl.odd(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized (pcl){
System.out.println("Releasing lock on pcl ");
pcl.notify();
}
System.out.println("ThredE has finished its working");
}
}
class PrintCl {
public void Even(int n) throws InterruptedException {
synchronized (this) {
System.out.println("even - "+n);
this.notifyAll();
this.wait();
}
}
public void odd(int n) throws InterruptedException {
synchronized (this) {
System.out.println("odd "+n);
this.notifyAll();
this.wait();
}
}
}
I'm a little stumped. Below is pretty much a copy and paste from A simple scenario using wait() and notify() in java.
To my understanding, this Java program below should be printing yumyum.. to the screen but it isn't. I am in Eclipse for Mac OS X. Any ideas what I'm doing wrong ?
public class Main {
public static void main(String[] args) {
MyHouse house = new MyHouse();
house.eatPizza();
house.pizzaGuy();
}
}
class MyHouse extends Thread {
private boolean pizzaArrived = false;
public void eatPizza() {
synchronized (this) {
while (!pizzaArrived) {
try {
wait();
} catch (InterruptedException e) {
}
}
}
System.out.println("yumyum..");
}
public void pizzaGuy() {
synchronized (this) {
this.pizzaArrived = true;
notifyAll();
}
}
}
You have one thread. The single thread will wait indefinitely (it needs to be notified by another thread). Try creating another thread in which one will eatPizza() and one will pizzaGuy
Try this...
public class Main {
public static void main(String[] args) {
MyHouse house = new MyHouse();
house.start();
// house.eatPizza();
// Halt main thread momentarily to delay Mr Pizza Guy
try { Thread.sleep(3000); } catch(Exception e) {}
house.pizzaGuy();
}
}
class MyHouse extends Thread {
private boolean pizzaArrived = false;
private Object lock = new Object();
#Override
public void run() {
eatPizza();
}
public void eatPizza() {
synchronized (lock) {
while (!pizzaArrived) {
try {
System.out.println("Waiting for Pizza guy");
lock.wait();
} catch (InterruptedException e) {
}
}
System.out.println("Pizza arrived!!!");
}
System.out.println("yumyum..");
}
public void pizzaGuy() {
synchronized (lock) {
this.pizzaArrived = true;
lock.notifyAll();
}
}
}
Try below code working fine.
public class WaitNotify {
private static int i = 1;
private static boolean flag = false;
static Object obj = new Object();
public static void main(String[] args) {
Thread t1 = new Thread(new Runnable(){
#Override
public void run() {
while(i<10){
synchronized (obj) {
try {
if(i%2 == 0){
obj.wait();
}
System.out.println("t1 -> " + i++);
obj.notify();
Thread.currentThread().sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
});
Thread t2 = new Thread(new Runnable(){
#Override
public void run() {
while(i<10){
synchronized (obj) {
try {
if(i%2 != 0){
obj.wait();
}
System.out.println("t2 -> " + i++);
obj.notify();
Thread.currentThread().sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
});
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
How to write a simple fair lock analog to new ReentrantLock(true)?
public class Main1 {
public static void main(String[] args) {
// Lock lock = new ReentrantLock(true);
CustomLock lock = new CustomLock();
new Thread(new Producer(lock)).start();
new Thread(new Consumer(lock)).start();
}
}
class Producer implements Runnable {
private Lock lock;
private CustomLock customLock;
public Producer(Lock lock) {
this.lock = lock;
}
public Producer(CustomLock lock) {
this.customLock = lock;
}
#Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
// lock.lock();
customLock.lock();
System.out.println("Producer before");
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Producer after");
// lock.unlock();
customLock.unlock();
}
}
}
class Consumer implements Runnable {
private Lock lock;
private CustomLock customLock;
public Consumer(Lock lock) {
this.lock = lock;
}
public Consumer(CustomLock lock) {
this.customLock = lock;
}
#Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
// lock.lock();
customLock.lock();
System.out.println("Consumer before");
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Consumer after");
// lock.unlock();
customLock.unlock();
}
}
}
class CustomLock{
private boolean isLocked;
public synchronized void lock(){
while (isLocked) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
isLocked = true;
}
public synchronized void unlock(){
if(isLocked){
isLocked = false;
notify();
}
}
}
Custom not fair Lock (I am not sure that it's correct)
class CustomLock{
private boolean isLocked;
public synchronized void lock(){
while (isLocked) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
isLocked = true;
}
public synchronized void unlock(){
if(isLocked){
isLocked = false;
notify();
}
}
}
If you want a fair lock you need to use a list and notify threads following the list order.