I am a beginner and I have to write a code for particular prob stmt. I wanna use locks to implement it. Beforehand, I gotto know the working of locks and its methods.
In my below code, I need the first thread to await and second thread to signal the first thread and wake up. But the signal is not waking up my waiting thread. Could anyone pls help.
package com.java.ThreadDemo;
import java.util.Collection;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ThreadEx {
public static void main (String args[]) throws InterruptedException
{
ThreadMy mt[]=new ThreadMy[6];
int a=1, b=2;
mt[1] = new ThreadMy(a);
mt[2] = new ThreadMy(b);
mt[1].start ();
Thread.sleep(100);
mt[2].start ();
}
}
class ThreadMy extends Thread
{
final ReentrantLock rl = new ReentrantLock() ;
Condition rCond = rl.newCondition();
//private final Condition wCond = rl.newCondition();
int i;
int c;
public ThreadMy(int a)
{
c=a;
}
public void run()
{
System.out.print("\nThread "+c+" "+rl.isHeldByCurrentThread()+" "+rl.isLocked() );
rl.lock();
try
{
//for (i=0;i<2;i++)
System.out.print("\nThread "+c+" "+rl.isHeldByCurrentThread()+" "+rl.getHoldCount() );
try
{
if (c==1)
{
System.out.print("await\n");
rCond.await();
//rCond.await(200, TimeUnit.MILLISECONDS);
System.out.print("signal\n");
}
else
{
System.out.print("P");
rCond.signal();
Thread.sleep(2000);
System.out.print("P1");
}
//rCond.signal();
}
catch ( InterruptedException e)
{
//System.out.print("Exception ");
}
}
finally
{
rl.unlock();
}
System.out.print("\n run " + c);
}
}
You are not sharing lock and condition between threads. Each instance of ThreadMy is running with its own lock and condition object.
Related
Need help with code at below link as it should run indefinitely likewise with any typical producer/consumer problem but somehow it is getting stuck on call of condition.signal(). What am I doing wrong here?
In main method, I have created two thread, one is consumer and other one is producer. it has shared task queue where both updates the entry.
package com.anurgup.handson;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ConditionService implements Runnable {
Lock lock = new ReentrantLock();
Condition added = lock.newCondition();
Condition removed = lock.newCondition();
// type of service
String type;
// shared task for insertion and deletion of task
static Queue<Integer> task = new PriorityQueue<Integer>();
// max number of task allowed
private static final int MAX_SIZE = 5;
public ConditionService(String type) {
this.type = type;
}
public static void main(String[] args) {
ExecutorService service = Executors.newFixedThreadPool(2);
service.submit(new ConditionService("producer"));
service.submit(new ConditionService("consumer"));
}
public void produce() {
try {
while (true) {
System.out.println("in producer...");
synchronized (task) {
while (task.size() == MAX_SIZE)
removed.await();
System.out.println("added item: " + task.size());
task.add(task.size());
added.signal();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void consume() {
try {
while (true) {
System.out.println("in consumer...");
synchronized (task) {
while (task.isEmpty())
added.await();
System.out.println("removed item: " + task.peek());
task.remove();
removed.signal();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
#Override
public void run() {
if (this.type.equals("producer"))
this.produce();
else
this.consume();
}
}
You're making two mistakes. First, your lock and conditions need to be static, or each task will only synchronize and wait on itself. Second, you need to use lock.lock(), not synchronized. It should look like this:
lock.lock();
try {
// wait
// produce/consume
} finally {
lock.unlock();
}
The counter variable does not accurately reflect how many times increment
method is invoked. Why not, and how can it be fixed? (You do not have to write code,
just use English.)
Original:
import java.util.*;
import java.lang.*;
import java.io.*;
class Foopadoop
{
public static int counter = 0;
public static void main(String[] args) throws Exception {
Runnable r = new Runnable() {
public void run() {
while(true){
counter++;
}
}
};
Thread t1 = new Thread(r);
Thread t2 = new Thread(r);
t1.start();
t2.start();
}
}
Mine, I added a semaphore but I'm not sure if I'm doing it right or am I suppose to use a lock.
import java.util.*;
import java.lang.*;
import java.io.*;
import java.util.concurrent.Semaphore;
class Foopadoop
{
public static int counter = 0;
Semaphore lock = new Semaphore(0);
public static void main(String[] args) throws Exception {
Runnable r = new Runnable() {
try{public void run() {
while(true){
counter++;
lock.acquire();
}
}
}finally{
lock.release();
}
};
Thread t1 = new Thread(r);
Thread t2 = new Thread(r);
t1.start();
t2.start();
}
}
That's not how you use a Semaphore.
You acquire it before you access the shared resource, and release it after:
while (true) {
try {
lock.acquire();
counter++;
} finally {
lock.release();
}
}
Since you acquire first, you will also need at least 1 permit, otherwise there is nothing to acquire:
static Semaphore lock = new Semaphore(1);
A synchronized block is easier than a Semaphore:
while (true) {
synchronized (Foopadoop.class) {
counter++;
}
}
or an AtomicInteger:
static AtomicInteger counter = new AtomicInteger();
// ...
while (true) {
counter.getAndIncrement();
}
Also you can add Thread.sleep(ms) inside the while loop, so that it will pause the current thread for some time, & start executing other threads. Otherwise the current thread might run in a selfish manner (selfish thread).
I research concurrecy in java. Recently I learn wait and notify methods meaning.
Now I think that sometimes I should to solve following problem:
I have
class ThreadGroup1 extends Thread
and
class ThreadGroup2 extends Thread
I have 300 instances of every Thread and start simultaneously (for example by means of CountDownLatch )
And I have synchronized section:
synchronized(SharedObjectBetweenThreads){...}
I want to get following behaviour:
instance of ThreadGroup1 acquire the section
instance of ThreadGroup2 acquire the section
instance of ThreadGroup1 acquire the section
instance of ThreadGroup2 acquire the section
and so on.
I think you understand what I want.
I know that if I would use wait and notify I cannot guarantee which next thread from waiting queue will acquire section.
How can I solve described issue?
P.S.
This issue relates with question "how to notify concrete thread?"
P.S.
my current sketch
public class ConditionTest {
public static void main(String [] args){
List<Thread> threads = new ArrayList<>();
for(int i=0 ;i<10;i++) {
threads.add(new Thread1());
threads.add(new Thread2());
}
for(Thread thread : threads){
thread.start();
}
}
public static synchronized void method() throws InterruptedException {
System.out.println(Thread.currentThread());
Thread.sleep(500);
}
}
class Thread1 extends Thread{
static int index =0;
int number;
#Override
public void run(){
try {
ConditionTest.method();
} catch (InterruptedException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
#Override
public String toString(){
return "group1-" + number;
}
Thread1(){
number= index++;
}
}
class Thread2 extends Thread{
static int index =0;
int number;
#Override
public void run(){
try {
ConditionTest.method();
} catch (InterruptedException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
#Override
public String toString(){
return "group2-" + number;
}
Thread2(){
number= index++;
}
}
please help to correct this.
According hoaz answer I got resolving.
please review this code:
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ConditionTest {
static Integer CountThreadInGroup = 10;
public static void main(String[] args) throws InterruptedException {
Lock lock = new ReentrantLock();
boolean isFirstShouldExecute = true;
Condition isFirstExpected = lock.newCondition();
Condition isSecondExpected = lock.newCondition() ;
Synchronizator synchronizator = new Synchronizator(isFirstShouldExecute, lock,isFirstExpected,isSecondExpected);
List<Thread> threads = new ArrayList<>();
for (int i = 0; i < CountThreadInGroup; i++) {
threads.add(new Thread1(synchronizator));
}
for (Thread thread : threads) {
thread.start();
}
threads.clear();
Thread.sleep(100);
for (int i = 0; i < CountThreadInGroup; i++) {
threads.add(new Thread2(synchronizator));
}
for (Thread thread : threads) {
thread.start();
}
}
public static void method() throws InterruptedException {
System.out.println(Thread.currentThread());
Thread.sleep(500);
}
}
class Thread1 extends Thread {
static int index = 0;
int number;
private final Synchronizator synchronizator;
#Override
public void run() {
synchronizator.lock.lock();
try {
while (!synchronizator.isFirstExpected) {
synchronizator.isFirstShouldExecute.await();
System.out.println(Thread.currentThread() + " woke up");
}
ConditionTest.method();
synchronizator.isFirstExpected = false;
synchronizator.isSecondShouldExecute.signal();
} catch (InterruptedException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} finally {
synchronizator.lock.unlock();
}
}
#Override
public String toString() {
return "\t\t\t group1-" + number;
}
Thread1(Synchronizator synchronizator) {
this.synchronizator = synchronizator;
number = index++;
}
}
class Thread2 extends Thread {
static int index = 0;
int number;
private final Synchronizator synchronizator;
#Override
public void run() {
synchronizator.lock.lock();
try {
while (synchronizator.isFirstExpected) {
synchronizator.isSecondShouldExecute.await();
System.out.println(Thread.currentThread() + " woke up");
}
ConditionTest.method();
synchronizator.isFirstExpected = true;
synchronizator.isFirstShouldExecute.signal();
} catch (InterruptedException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} finally {
synchronizator.lock.unlock();
}
}
#Override
public String toString() {
return "\t\t\t\t\t\t group2-" + number;
}
Thread2(Synchronizator synchronizator) {
this.synchronizator = synchronizator;
number = index++;
}
}
class Synchronizator{
volatile boolean isFirstExpected ;
Lock lock ;
Condition isFirstShouldExecute;
Condition isSecondShouldExecute;
Synchronizator(boolean isFirstExpected, Lock lock, Condition isFirstShouldExecute, Condition isSecondShouldExecute){
this.isFirstExpected = isFirstExpected;
this.lock =lock;
this.isFirstShouldExecute = isFirstShouldExecute;
this.isSecondShouldExecute = isSecondShouldExecute;
}
}
You can find Condition and ReentrantLock classes useful in this case:
Lock lock = new ReentrantLock();
Condition threadGroup1 = lock.newCondition();
Condition threadGroup2 = lock.newCondition();
volatile boolean isFirstGroupRunning = true;
Pass all four to each thread in both groups. You can actually compose them into new class.
In first thread group use following code:
lock.lock();
try {
while (!isFirstGroupRunning) threadGroup2.await();
// do whatever you need to do in first thread
isFirstGroupRunning = false;
threadGroup1.signal();
} finally {
lock.unlock();
}
In second thread group do similar await / signal sequence:
lock.lock();
try {
while (isFirstGroupRunning) threadGroup1.await();
// do whatever you need to do in second thread
isFirstGroupRunning = true;
threadGroup2.signal();
} finally {
lock.unlock();
}
First, I suggest you not extend Thread nor call the class ThreadGroup1, etc. ThreadGroup is a core class, and there is typically no reason to extend Thread. The best way to handle the logic executed in a thread is to implement Runnable and pass instances of that class to new Thread(myRunnableInstance).
I don't think I understand what you want to really do, but it doesn't sound like threads are the way to go. Threads are meant to run multiple process at the same time, not to do them in a sequence.
It sounds like you might want a different concurrent design, maybe a 'producer consumer model' if you have two separate 'Thread groups' that are acquiring a synchronised block sequentially. In which case you could have both thread groups interacting with the same BlockingQueue. It really depends on what these threads are doing.
See
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/BlockingQueue.html
I am trying to write a basic program using threads. Assuming I have two threads, t1 and t2 and lock x. Assuming lock x is assigned to t1. When would be a situation where t2 would be unable to process due to lock x being assigned to t1? I am trying to create a simple example to demonstrate how locks/threads work.
I appreciate any assistance in this matter.
This is what I got so far:
Class Skywalker:
import java.util.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Skywalker{
public static void main(String args[]){
Thread t1 = new Thread("station 1");
Thread t2 = new Thread("station 2");
t1.start();
t2.start();
}
}
Class Darth:
import java.util.Random;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Darth implements Runnable{
String stationName;
Lock x = new ReentrantLock();
Random r = new Random();
public Darth(String name){
stationName = name;
}
public void run(){
try{
x.lock();
System.out.println(stationName + "is working");
sleep(randomTime);
x.unlock();
} catch(Exception e) {
}
}
}
You should put the lock in one single class to protect a "resource access", for instance:
class SharedResource {
private static Lock lock = new ReentrantLock();
public static void consumeResource(){
try{
lock.lock();
//just one thread a time here
int i = 10;
//mock consuming shared resource:
while(i>0){
i--;
System.out.println(Thread.currentThread().getName() + " is in");
Thread.sleep(1000);
}
}finally{
lock.unlock();
}
}
}
Now just one thread a time will be able to access the lines of code in consumeResource method that are within the lock/unlock statements. It is easy to show that invoking consumeResource from Darth run method.
Let's say we have this simple example:
public Example extends Thread{
String temp;
public Example(){
}
#Override
public void run(){
.
.
.
.
temp = "a_value";
}
public static void main(String[] args) {
Example th = new Example();
th.start();
}
}
How can the Thread after finishing its job return me the String temp?
Make use of the (relatively) new Callable<T> instead of Runnable (available in 1.5 and newer versions):
Here is a (simple) example:
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Main {
public static void main(final String[] argv) {
final ExecutorService service;
final Future<String> task;
service = Executors.newFixedThreadPool(1);
task = service.submit(new Foo());
try {
final String str;
// waits the 10 seconds for the Callable.call to finish.
str = task.get(); // this raises ExecutionException if thread dies
System.out.println(str);
} catch(final InterruptedException ex) {
ex.printStackTrace();
} catch(final ExecutionException ex) {
ex.printStackTrace();
}
service.shutdownNow();
}
}
class Foo implements Callable<String> {
public String call() {
try {
// sleep for 10 seconds
Thread.sleep(10 * 1000);
} catch(final InterruptedException ex) {
ex.printStackTrace();
}
return ("Hello, World!");
}
}
Look at Future interface javadoc. It has sample usage showing you how to do this.
You can achieve this by the Observer pattern.
on finishing the thread notifies all listeners that it's finished and they can retrieve the value (through a getter). Or it can even already send the computed value.
Or you can use a task, see FutureTask, a runnable ( indeed as stated below a Callable ) that returns a result and can throw exceptions.
If you don't want to swap the solution to use Callable objects then you can use also queues and return the result from the threads that way.
I re-wrote your example like this:
import java.util.PriorityQueue;
import java.util.Queue;
public class GetResultFromThread {
public static void main(String[] args) throws Exception {
Queue<String> queue = new PriorityQueue<String>();
int expectedResults = 2;
for (int i = 0; i < expectedResults; i++) {
new Example(queue).start();
}
int receivedResults = 0;
while (receivedResults < expectedResults) {
if (!queue.isEmpty()) {
System.out.println(queue.poll());
receivedResults++;
}
Thread.sleep(1000);
}
}
}
class Example extends Thread {
private final Queue<String> results;
public Example(Queue<String> results) {
this.results = results;
}
#Override
public void run() {
results.add("result from thread");
}
}
Note that you shall think of synchronization and concurrency!