Basically, I am trying to implement a mechanism where I have two threads going in parallel. Thread1 is continuously updating a counter value. When the counter value reaches increments of specific values (ex. multiple of 100, 250, 500), then I want Thread2 to execute a specific task selected on the counter value in parallel. Thread1 should continue counting but it should not count past the key value if Thread2 has not completed its' task.
Use case: Thread 1 has updated the counter to be 100. This dispatches Thread2 to perform TaskA. Thread1 is counting still. The counter reaches 250. If Thread2 has finished its' task, Thread1 should continue. Otherwise, Thread1 should wait for TaskA to be finished before proceeding.
|t2 |t1
| |
| |
| |
______100________ <----start thread 2 real quick
| |
| |
| |
| |
| |
| |
_______250______ <------at this point just wait for taskA to finish
| | IF it's not finished. If it is, start taskB and
| | continue counting
V V
I've been hacking at the problem for a bit but I've scrapped everything so far. I'd appreciate code/pseudocode/hints/advice. Thanks in advance
The CyclicBarrier can be used to create a barrier where the threads would wait for the other thread. So, below, there are two threads 'countingThread' and 'taskThread'. The 'countingThread' would perform its counting and would invoke the 'await' when the counting has reached a specific point, (method-'checkBarrierCondition' below).
As per the example in the question, when the counting-thread reaches 100, it can call 'await' on the barrier and if the task-thread has completed its task by that time, the barrier would snap and both would proceed to next activities. If the task has not been completed yet, then the counter thread will wait for the task-performing thread.
All the locking is handled by CyclicBarrier and concurrent framework
public class Threading {
public void execute() {
final CyclicBarrier barrier = new CyclicBarrier(2);
Thread countingThread = new Thread(new Tasker(barrier));
Thread taskThread = new Thread(new Counter(barrier));
countingThread.start();
taskThread.start();
try {
countingThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new Threading().execute();
}
class Tasker implements Runnable {
private CyclicBarrier barrier;
Tasker(CyclicBarrier barrier) {
this.barrier = barrier;
}
public void run() {
String task = "taskA"; //just some mock-up task name
while (!allTasksDone(task)) {
task = performTask(task);
try {
System.out.println("Tasker : Await on barrier ");
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
}
class Counter implements Runnable {
private CyclicBarrier barrier;
Counter(CyclicBarrier barrier) {
this.barrier = barrier;
}
public void run() {
int counter = 0; //just for the sake of example; starting at 0
while (!isCountingDone(counter)) {
counter = performCounting(counter);
if (checkBarrierCondition(counter)) {
try {
System.out.println("Counter : Await on barrier ");
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
}
}
}
you probably want to use locks? consider this - counter:
import java.util.concurrent.locks.Lock;
public class ThreadOne extends Thread {
private ThreadTwo two;
private Lock lock;
public ThreadOne(Lock l, ThreadTwo two) {
this.two = two;
this.lock = l;
this.start();
}
#Override
public void run() {
int i = 0;
while(true) {
if(i%100==0) {
// tell other thread to start
two.startRunning();
while(two.pending()) {
// wait until it actually started
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
// acquire the lock (or wait)
lock.lock();
try {
// count up
i++;
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
}
execution thread:
import java.util.concurrent.locks.Lock;
public class ThreadTwo extends Thread {
private boolean pending = false;
private Lock lock;
public ThreadTwo(Lock l) {
this.lock = l;
this.start();
}
public void startRunning() {
pending = true;
}
public boolean pending() {
return pending;
}
#Override
public void run() {
while(true) {
try {
Thread.sleep(200);
} catch (Exception e) {
}
if(pending) {
lock.lock();
try {
pending = false;
execute();
} catch (Exception e) {
} finally {
lock.unlock();
}
}
}
}
private void execute() {
}
}
and how to start them.
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Main {
public static void main(String[] args) {
Lock l = new ReentrantLock();
ThreadTwo two = new ThreadTwo(l);
ThreadOne one = new ThreadOne(l,two);
}
}
package testRandomStuff;
public class ThreadingPuzzle {
public int countMax = 25;
public int factor = 5;
public Thread threadA, threadB;
private class Signal {
public volatile boolean flag = true;
public Signal(boolean initial) {
flag = initial;
}
public synchronized void setFlag() {
flag = true;
notifyAll();
}
public synchronized void unsetFlag() {
flag = false;
notifyAll();
}
public synchronized boolean getFlag() {
return flag;
}
}
public Signal checkpoint = new Signal(true);
public Signal doWork = new Signal(false);
Runnable threadARunnable = new Runnable() {
#Override
public void run() {
for (int i = 0; i < countMax; i++) {
if (i % factor == 0) {
if (checkpoint != null) {
// --------mechanism to wait for threadB to finish---------
synchronized (checkpoint) {
try {
// -----use while loop to prevent spurious wakeup------
// Checkpoint flag is true in the first iteration, no need to wait.
while (!checkpoint.getFlag()) {
checkpoint.wait();
}
} catch (InterruptedException ie) {
// handle exception
}
}
// ThreadB has finished last job when threadA leaves the above sync-block
}
// ------ start threadB real quick---------
// unset checkpoint flag, so that threadA will not proceed the next
// interation without threadB setting the flag first.
// send signal to threadB to wake it up
checkpoint.unsetFlag();
doWork.setFlag();
}
System.out.println("Thread A - count:"+i);
}
}
};
Runnable threadBRunnable = new Runnable() {
#Override
public void run() {
while (true) {
// --------mechanism to wait for threadA send job---------
synchronized (doWork) {
try {
// -----use while loop to prevent spurious wakeup------
// doWork flag is false in the first iteration, wait for ThreadA.
while (!doWork.getFlag()) {
doWork.wait();
}
} catch (InterruptedException ie) {
// handle exception
}
}
doWork.unsetFlag();
// -----------do what ever you need to do in threadB-----------
System.out.println("Thread B - do some work");
try {
Thread.sleep(1000);
} catch (InterruptedException ie) {
}
System.out.println("Thread B - done working");
// ------------Finish work, notify threadA---------
checkpoint.setFlag();
}
}
};
public ThreadingPuzzle() {
// FIXME Auto-generated constructor stub
}
public static void main(String[] args){
ThreadingPuzzle puzzle = new ThreadingPuzzle();
puzzle.threadA = new Thread(puzzle.threadARunnable);
puzzle.threadB = new Thread(puzzle.threadBRunnable);
puzzle.threadA.start();
puzzle.threadB.start();
}
}
SIMULATION RESULTS
Thread B - do some work
Thread A - count:0
Thread A - count:1
Thread A - count:2
Thread A - count:3
Thread A - count:4
Thread B - done working
Thread B - do some work
Thread A - count:5
Thread A - count:6
Thread A - count:7
Thread A - count:8
Thread A - count:9
Thread B - done working
Thread B - do some work
Thread A - count:10
Thread A - count:11
Thread A - count:12
Thread A - count:13
Thread A - count:14
Thread B - done working
Thread B - do some work
Thread A - count:15
Thread A - count:16
Thread A - count:17
Thread A - count:18
Thread A - count:19
Thread B - done working
Thread B - do some work
Thread A - count:20
Thread A - count:21
Thread A - count:22
Thread A - count:23
Thread A - count:24
Thread B - done working
Thread B - do some work
Thread B - done working
I would suggest have a look at Java's executor service. It really abstracts most of the complexities associated with multiple threads. Plus you can easily increase number of threads executing tasks if required in future. Basically you run counting in your first thread. When you want to execute a task in another thread you simply create a callable. The API will return you a future(s) for your callable(s). When you have finished processing/counting in thread1 you simply call get or getValue on your future from thread1. Now the beauty of this is that it will return you the result immediately if other thread has finished processing. If other thread is busy processing the task then it will block your thread1 until result is returned. Please note that you don't need to do any locking, blocking or notifying manually. Don't forget to use threadsafe collections if you are sharing data between multiple threads. Hope this helps!
Related
I want to display this two threads alternatively like that :
Thread 1
Thread 0
Thread 1
Thread 0
...
That's the basic code from where I started, I tried with wait() notify() Methods but I couldn't get the result wanted.
class Task extends Thread {
#Override
public void run() {
try {
for(int i = 0; i<10; i++){
double dure = Math.random()*200 ;
sleep((long) dure);
System.out.println(Thread.currentThread().getName());
}
} catch (Exception e) {
}
}
}
public class App {
public static void main(String[] args) {
Task t1 = new Task() ;
Task t2 = new Task() ;
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
}
}
} ```
I see two solutions:
Busy Wait
Each thread wait before printing. And release when the condition is true. I used AtomicInteger for indexToPrint to make this value sync for every thread.
This solution works with n number of threads.
import java.util.concurrent.atomic.AtomicInteger;
class Task extends Thread {
final static private AtomicInteger indexToPrint = new AtomicInteger(0);
static private int threadNumber = 0;
final private int index;
/**
*
*/
public Task() {
index = threadNumber++;
}
private int nextIndex() {
return (index + 1) % threadNumber;
}
#Override
public void run() {
try {
for(int i = 0; i<10; i++){
double dure = Math.random()*200 ;
sleep((long) dure);
while (indexToPrint.get() != index) {
sleep((long) 10);
}
indexToPrint.set(nextIndex());
System.out.println(Thread.currentThread().getName());
}
} catch (Exception e) {}
}
}
wait and notify
A bit more complex to understand, but no useless CPU use. Let's explain how the synchronized block synchronized (indexToPrint) {...} works.
The block is synchronized monitoring the static object indexToPrint. This object is static (common to every thread), so only one thread can simultaneously enter this block.
When one thread enter the block, if its index is different from indexToPrint then the thread is stopped with wait() making it possible for another thread to enter the block. Else, the thread name is printed, the indexToPrint is updated to next thread index and all thread are waken up with notifyAll(). Finally, it left the block.
All threads waiting are now awake, and the actual thread left the block. So one thread can try again to print.
It's important to understand that when a thread is put to wait and then notify, it runs exactly where it was stopped. Here, a thread can be stopped at two positions: before the synchronized block and at the wait call.
The while is very essential here. All thread are waking up with notifyAll(), so after waking up they should test themselves again.
You can find a good documentation here.
The code is based on the previous one. With same use of indexToPrint.
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicInteger;
class Task extends Thread {
static private final AtomicInteger indexToPrint = new AtomicInteger(0);
static private int threadNumber = 0;
final private int index;
final private static ArrayList<Task> tasks = new ArrayList<>();
/**
*
*/
public Task() {
index = threadNumber++;
tasks.add(this);
}
private int nextIndex() {
return (index + 1) % threadNumber;
}
#Override
public void run() {
try {
for(int i = 0; i<10; i++){
double dure = Math.random()*200 ;
sleep((long) dure);
synchronized (indexToPrint) {
while (indexToPrint.get() != index) {
indexToPrint.wait();
}
indexToPrint.set(nextIndex());
System.out.println(Thread.currentThread().getName());
indexToPrint.notifyAll();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
The random sleep time can cause the unexpected result also within the main method making the main thread sleep between the start of Thread1 and Thread2 can help you to know who is the first thread that will start the print task , after that you should give the right sleep time inside the task to give the Threads the possibility to prints alternatively .
class Task extends Thread {
#Override
public void run() {
try {
for(int i = 0; i<10; i++){
sleep(2000);
System.out.println(Thread.currentThread().getName());
}
} catch (Exception e) {
}
}
}
public class App {
public static void main(String[] args) {
Task t1 = new Task() ;
Task t2 = new Task() ;
t1.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
t2.start();
}
}
I am trying to achieve that thread2 should complete first, then thread1, For this O am using join() method. But if I uncomment the System.out.println() present in the try block of thread1 class. then
code give null pointer exception. Why in try block I need to add line, it doesn't make any sense that adding a line code start working.
Demo class
public class Demo {
public static void main(String[] args) throws InterruptedException {
Thread1 t1 = new Thread1();
Thread2 t2 = new Thread2();
t1.start();
t2.start();
System.out.println("main Thread");
Thread.sleep(10);
}
}
Thread1 class
public class Thread1 extends Thread {
#Override
public void run() {
try {
// System.out.println(); // on adding anyline, this whole code works!!, uncommenting this line of code give NPE
Thread2.fetcher.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 0; i < 5; i++) {
System.out.println("in thread1 class, Thread-1 ");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Thread2 class
public class Thread2 extends Thread {
static Thread fetcher;
#Override
public void run() {
fetcher= Thread.currentThread(); // got the thread2
for (int i = 0; i < 5; i++) {
System.out.println("in thread2 class, Thread-2");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
OUTPUT of the program
in thread2 class Thread-2
Exception in thread "Thread-0" java.lang.NullPointerException
at org.tryout.Thread1.run(Thread1.java:22)
in thread2 class Thread-2
in thread2 class Thread-2
in thread2 class Thread-2
in thread2 class Thread-2
It is working purely by "pure luck" the
System.out.println();
internally calls synchronized, which is working as a delay that gives enough time for Thread 2 its field fetcher in:
fetcher= Thread.currentThread(); // got the thread2
In order to avoid this race-condition you need to ensure that the Thread 2 sets the field fetcher before Thread 1 accesses it. For that you case use, among others, a CyclicBarrier.
??A synchronization aid that allows a set of threads to all wait for
each other to reach a common barrier point.** CyclicBarriers are useful
in programs involving a fixed sized party of threads that must
occasionally wait for each other. The barrier is called cyclic because
it can be re-used after the waiting threads are released.
First, create a barrier for the number of threads that will be calling it, namely 2 threads:
CyclicBarrier barrier = new CyclicBarrier(2);
With the CyclicBarrier you can then force Thread 1 to wait for Thread 2 before accessing its field fetcher:
try {
barrier.await(); // Let us wait for Thread 2.
Thread2.fetcher.join();
} catch (InterruptedException | BrokenBarrierException e) {
// Do something
}
Thread 2 also calls the barrier after having setting up the field fetcher, accordingly:
fetcher = Thread.currentThread(); // got the thread2
try {
barrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
Both threads will continue their work as soon as both have called the barrier.
An example:
public class Demo {
public static void main(String[] args) throws InterruptedException {
CyclicBarrier barrier = new CyclicBarrier(2);
Thread1 t1 = new Thread1(barrier);
Thread2 t2 = new Thread2(barrier);
t1.start();
t2.start();
System.out.println("main Thread");
Thread.sleep(10);
}
}
public class Thread1 extends Thread {
final CyclicBarrier barrier;
public Thread1(CyclicBarrier barrier){
this.barrier = barrier;
}
#Override
public void run() {
try {
barrier.await();
Thread2.fetcher.join();
} catch (InterruptedException | BrokenBarrierException e) {
// Do something
}
for (int i = 0; i < 5; i++) {
System.out.println("in thread1 class, Thread-1 ");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Thread2 extends Thread {
static Thread fetcher;
final CyclicBarrier barrier;
public Thread2(CyclicBarrier barrier){
this.barrier = barrier;
}
#Override
public void run() {
fetcher = Thread.currentThread(); // got the thread2
try {
barrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
for (int i = 0; i < 5; i++) {
System.out.println("in thread2 class, Thread-2");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
If your code is not for education purposes, and you are not force to use any particular synchronization mechanism for learning purposes. In the current context you can simply pass the thread 2 as parameter of the thread 1, and call join directly on it as follows:
public class Demo {
public static void main(String[] args) throws InterruptedException {
Thread2 t2 = new Thread2();
Thread1 t1 = new Thread1(t2);
t1.start();
t2.start();
System.out.println("main Thread");
Thread.sleep(10);
}
}
public class Thread1 extends Thread {
final Thread thread2;
public Thread1(Thread thread2){
this.thread2 = thread2;
}
#Override
public void run() {
try {
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 0; i < 5; i++) {
System.out.println("in thread1 class, Thread-1 ");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Thread2 extends Thread {
#Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println("in thread2 class, Thread-2");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
This should allow your code to work properly. There is insufficient time between thread startups to allow fletcher to initialize.
try {
Thread.sleep(500);
Thread2.fetcher.join();
} catch (InterruptedException ie) {
}
For something this simple, the sleep should work. But for more complicated threads, appropriate synchronization is the key. And you should be aware that thread programming can be one of the most difficult aspects of programming to debug.
I got task from my professor related to Producer-Consumer problem.
The task is implement Producer-Consumer process, but
first process should increase its value by 5 each time
second process should divide its value by 2 each time.
I found some examples of code, but nothing about multiple processes. Here is one of them.
--
// Java program to implement solution of producer
// consumer problem.
import java.util.LinkedList;
public class Threadexample {
public static void main(String[] args)
throws InterruptedException
{
// Object of a class that has both produce()
// and consume() methods
final PC pc = new PC();
// Create producer thread
Thread t1 = new Thread(new Runnable() {
#Override
public void run()
{
try {
pc.produce();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
});
// Create consumer thread
Thread t2 = new Thread(new Runnable() {
#Override
public void run()
{
try {
pc.consume();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
});
// Start both threads
t1.start();
t2.start();
// t1 finishes before t2
t1.join();
t2.join();
}
// This class has a list, producer (adds items to list
// and consumber (removes items).
public static class PC {
// Create a list shared by producer and consumer
// Size of list is 2.
LinkedList<Integer> list = new LinkedList<>();
int capacity = 2;
// Function called by producer thread
public void produce() throws InterruptedException
{
int value = 0;
while (true) {
synchronized (this)
{
// producer thread waits while list
// is full
while (list.size() == capacity)
wait();
System.out.println("Producer produced-"
+ value);
// to insert the jobs in the list
list.add(value++);
// notifies the consumer thread that
// now it can start consuming
notify();
// makes the working of program easier
// to understand
Thread.sleep(1000);
}
}
}
// Function called by consumer thread
public void consume() throws InterruptedException
{
while (true) {
synchronized (this)
{
// consumer thread waits while list
// is empty
while (list.size() == 0)
wait();
// to retrive the ifrst job in the list
int val = list.removeFirst();
System.out.println("Consumer consumed-"
+ val);
// Wake up producer thread
notify();
// and sleep
Thread.sleep(1000);
}
}
}
}
}
Output:
Producer produced-0
Producer produced-1
Consumer consumed-0
Consumer consumed-1
Producer produced-2
I am not sure if I understand my task completely. Is it possible to implement given task on this code? I want you to give me some suggestions or any sources, so I can understand what to do.
Thank you all in advance!
If I correctly understand your problem from your description, you should change the field's value from two threads. You would like to create a class-level field and two synchronized methods for changing his value after that create two threads and call from them both operations alternately. I think you can write that:
public class Solution0 {
private volatile int count;
public synchronized void increment() throws InterruptedException {
count = count + 5;
Thread.sleep(1000);
notifyAll();
wait();
}
public synchronized void divide() throws InterruptedException {
count = count / 2;
Thread.sleep(1000);
notifyAll();
wait();
}
public static void main(String[] args) {
Solution0 solution = new Solution0();
Thread t1 = new Thread(() -> {
try {
while (true){
solution.increment();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread t2 = new Thread(() -> {
try {
while (true){
solution.divide();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
t1.start();
t2.start();
}
}
Also, you can change the type of field count from int to double, if you need a real number.
I have two thread classes: one that prints numbers from 0 to 9, and another from 100 to 109. What I want is to make the first thread wait for the other one to finish. For this, I used the join() method, but it's not working. Please tell me where I'm going wrong:
//demonstrates the use of join() to wait for another thread to finish
class AThread implements Runnable {
Thread t;
AThread() {
t = new Thread(this);
}
public void run() {
try {
for (int i=0; i<10; i++) {
System.out.println(i);
Thread.sleep(10);
}
} catch (InterruptedException e) {
System.out.println(t + " interruped.");
}
}
public void halt(Thread th) {
try {
th.join();
} catch (InterruptedException e) {
System.out.println(t + " interruped.");
}
}
}
//a different thread class (we distinguish threads by their output)
class BThread implements Runnable {
Thread t;
BThread() {
t = new Thread(this);
}
public void run() {
try {
for (int i=100; i<110; i++) {
System.out.println(i);
Thread.sleep(10);
}
} catch (InterruptedException e) {
System.out.println(t + " interruped.");
}
}
}
public class WaitForThread {
public static void main(String[] args) {
AThread t1 = new AThread();
BThread t2 = new BThread();
t1.t.start();
t1.halt(t2.t); //wait for the 100-109 thread to finish
t2.t.start();
}
}
You call join on the thread before it has started. That doesn't work; in that case, join will return immediately, it's not going to wait until the other thread has started and stopped later. You can see this in the API documentation:
Thread.join()
This implementation uses a loop of this.wait calls conditioned on this.isAlive.
Thread.isAlive()
Tests if this thread is alive. A thread is alive if it has been started and has not yet died.
Reorder the statements in your main method
t1.t.start();
t2.t.start();
t1.halt(t2.t); //wait for the 100-109 thread to finish
edit to answer your questions in the comments:
If you want the thread in AThread to wait for the thread in BThread to finish before doing its job, then you'll need to call join in AThread.run, and change your main method:
class AThread implements Runnable {
Thread t;
Thread threadToWaitFor;
AThread(Thread threadToWaitFor) {
t = new Thread(this);
this.threadToWaitFor = threadToWaitFor;
}
public void run() {
// First wait for the other thread to finish
threadToWaitFor.join();
// ...
}
// ...
}
public class WaitForThread {
public static void main(String[] args) {
BThread t2 = new BThread();
AThread t1 = new AThread(t2.t);
t2.t.start();
t1.t.start();
}
}
I am new to threading and semaphors, and I have some problem in synchronizing threads. For example, in the following code I want to do a pretty simple thing. To let one thread run, while other waits. For example, if it starts with the first thread, I want the second to wait for the first one to finish and then start. I really don't know what am I doing wrong.
Here is the code :
import java.io.*;
import java.util.concurrent.Semaphore;
public class ThreadTest {
public static void main(String[] args) throws InterruptedException {
Semaphore binaren = new Semaphore(1);
Runnable t1 = new T2(binaren);
Thread a = new Thread(t1);
Thread a2 = new T1(binaren);
System.out.println(binaren.availablePermits());
a.start();
a2.start();
}
}
class Work {
private static int a = 4;
public synchronized static void QQR(String s1)
{
for(int i=0;i<100;i++)
System.out.println(s1+" : "+(a++));
}
}
class T1 extends Thread
{
Semaphore sem;
public T1(Semaphore s1)
{
sem=s1;
}
public void run()
{
synchronized(this) {
if(!sem.tryAcquire()){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Work.QQR("T1");
sem.release();
notifyAll();
}
}
}
class T2 extends Thread
{
Semaphore sem;
public T2(Semaphore s1)
{
sem=s1;
}
#Override
public void run() {
synchronized(this) {
if(!sem.tryAcquire()){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Work.QQR("T2");
sem.release();
notifyAll();
}
}
}
The problem is that notify and notifyAll only wake up threads holding locks on the monitor being notified. But the t1 and t2 instances are waiting on themselves and are never awoken. You can have them wait on the semaphore for this simple test or introduce a new shared object to see how it works.
Use
sem.wait();
and
sem.notifyAll();
You can use Thread.join() on the first thread so that second thread will wait till the execution of this instance is not completed.