Understanding ReentrantLocks and Thread basics - java

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.

Related

there is a multithreads conflicts in this java program. how to explain it?

my program is:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class test implements Runnable{
private static int i;
private static volatile Integer vi = 0;
private static AtomicInteger ai = new AtomicInteger();
private static Integer si = 0;
private static int ri;
private static AtomicInteger flag = new AtomicInteger();
private Lock lock = new ReentrantLock();
#Override
public void run() {
for(int k=0;k<200000;k++){
i++;
vi++;
ai.incrementAndGet();
synchronized (si){
si++;
}
lock.lock();
try{
ri++;
}finally {
lock.unlock();
}
}
flag.incrementAndGet();
}
public static void main(String[] args) throws InterruptedException{
test t1 = new test();
test t2 = new test();
ExecutorService exec1 = Executors.newCachedThreadPool();
ExecutorService exec2 = Executors.newCachedThreadPool();
exec1.execute(t1);
exec1.execute(t2);
while(true){
if(flag.intValue()==2){
System.out.println("i>>>>>>"+i);
System.out.println("vi>>>>>>"+vi);
System.out.println("ai>>>>>>"+ai);
System.out.println("si>>>>>>"+si);
System.out.println("ri>>>>>>"+ri);
break;
}
Thread.sleep(50);
}
}
}
the result is:
vi>>>>>>340217
ai>>>>>>400000
si>>>>>>364359
ri>>>>>>397043
could someone help to explain how does this multithread programs works?
the result shows that vi is not equal to 400000 which is quite reasonable.
but why si and ri is not equal to 400000?
si is sychronized and ri is sychronized by locks.
You aren't synchronizing access to the variables in the main thread.
You need the same synchronization/lock around the variables in order to guarantee the visibility of updates.
However, your synchronization on si probably doesn't work as you intend, because you keep assigning a new value to that field: synchronized on test.class instead.
Similarly the synchronization conferred by the lock probably doesn't work as you intend, because each test instance has its own lock.
lock is not static, hence each thread uses different instance, as you create two instances of test, hence ri is not synchronized. si is not synchronized, because integer is immutable, but si++ does unboxing, increment and boxing. You should synchronize on another final object that is static for ex. or use one instance of test:
private final Object lockObj = new Object();
...
synchronized(lockObj){
si++;
}

Java Multi threading semaphore

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).

Working of Await and signal in concurrent Java

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.

Thread behaviour in Java

I am running the program below but for some reason, it dosen't look like I am getting to the run() method. Basically I am trying to spot the behaviour of threads.I am getting the result below :
pqni392fr8dchsdmajglvuqsof
pqni392fr8dchsdmajglvuqsof has wake up
l79uho1tjtot7pcmk4vhh5t8qc
l79uho1tjtot7pcmk4vhh5t8qc has wake up
adfapus6g1fst56daimrudkgji
adfapus6g1fst56daimrudkgji has wake up
iqfo9knc99kcb622g36c77m62
iqfo9knc99kcb622g36c77m62 has wake up
67vdpghqit1a4iv3593451ps0a
67vdpghqit1a4iv3593451ps0a has wake up
As you see I am not getting to the run() method where a thread should sleep.what is the problem?
And another question, could a thread execute the run() from the first run of the program because I noticed that the first line of the output is always from the main().
Thank you.
import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.logging.Level;
import java.util.logging.Logger;
class myThread implements Runnable {
#Override// method run is to be executed by a new thread
public void run() {
System.out.println("I am here");
int timeRandom = new Random().nextInt(50);
try {
String ThrName = Thread.currentThread().getName();
Thread.sleep(timeRandom);
System.out.println("Thread " + ThrName + " sleeping " + timeRandom);
} catch (InterruptedException ex) {
Logger.getLogger(myThread.class.getName()).log(Level.SEVERE, null, ex);
}
// throw new UnsupportedOperationException("Not supported yet.");
}
}
class myClass {
static int nthread = 5;
public static void main(String[] args) {
ExecutorService myService = Executors.newFixedThreadPool(nthread);
while (nthread != 0) {
Thread.currentThread().setName(new BigInteger(130, new SecureRandom()).toString(32));
System.out.println(Thread.currentThread().getName());
myService.submit(Thread.currentThread());
System.out.println(Thread.currentThread().getName() + " has wake up");
//
nthread -= 1;
}
myService.shutdown();
}
}
You never pass an instance of myThread to your ExecutorService, and instead you are performing everything related onto the current thread.
Your code:
Thread.currentThread().setName(new BigInteger(130, new SecureRandom()).toString(32));
System.out.println(Thread.currentThread().getName());
myService.submit(Thread.currentThread());
Code creating expected results:
Thread myThread = new Thread(new myThread());
myThread.setName(new BigInteger(130, new SecureRandom()).toString(32));
System.out.println(myThread.getName());
myService.submit(myThread);
Also, as a side note, Java conventions dictate that class names are declared with capital letters; myClass should be MyClass and myThread should be myThread. That's irrelevant to the runtime issue though.
You are submitting the main thread for your application as a Runnable to the ExecutorService repeatedly. I'm not sure what the defined behavior (if any, could be undefined) of calling run() on the main thread is, but it is certainly not correct. You want to create new myThread objects and submit them to the ExecutorService instead.

Thread Waits for a lock when it shouldn't be

i am practicing on java threads, and i am confused with Locking mechanism,
What i am trying to achieve is when a thread is taking much time to execute a block of code whose lock it has acquired, the other thread should just not wait and go for the else condition,
this is my code as follows
import java.util.concurrent.locks.*;
import java.util.concurrent.*;
class MySharedData{
private volatile boolean bFlag;
private int counter=1;
public void abuseIt() throws Exception{
while(!bFlag){
System.out.println(" THREAD "+Thread.currentThread().getName()+" WITH COUNTER "+counter);
counter++;
Thread.sleep(1000);
if(counter > 20){
bFlag=true;
}
}
}
}
class RequesterThree implements Runnable{
private Lock lock;
RequesterThree(){
lock = new ReentrantLock();
}
#Override
public void run(){
MySharedData myShared = null;
try{
myShared = new MySharedData();
if(lock.tryLock(250,TimeUnit.MILLISECONDS)){
myShared.abuseIt();
}else{
System.out.println(Thread.currentThread().getName()+": SHARED DATA IS NON-ACCESSIBLE !!!!");
}
}catch(Exception e){
System.out.println(e);
}finally{
lock.unlock();
}
}
}
public class Ex03{
public static void main(String [] args){
Thread[] requests = new Thread[]{
new Thread(new RequesterThree(),"MICHEAL"),
new Thread(new RequesterThree(),"SHAWN"),
new Thread(new RequesterThree(),"JOHN"),
new Thread(new RequesterThree(),"TRON"),
new Thread(new RequesterThree(),"FINCH")
};
for(int x=0; x < requests.length; x++){
requests[x].start();
}
}
}
But here all of the five threads wait for the lock, and not a single thread prints the SOP in the else condition,
What i am expecting is,
When Thread T1 is started, it acquires the lock, and execute the abuseIt() method, there it sleeps for 1 sec,
Now thread T2 should wait for the lock to get free for only 250 milisec, but T1 is any how waiting for 1 sec, so T2 should execute the else condition in the run method,
How can i achieve this,
In your code, each RequesterThree object has a separate lock, so there is no synchronization across them.
Additionally, each thread calls myShared.abuseIt() on its own dedicated instance of MySharedData.
To fix:
private static final Lock lock = new ReentrantLock();
private static final MySharedData myShared = new MySharedData();
Also, remove the constructor and the change the run() method:
#Override
public void run(){
try{
if(lock.tryLock(250,TimeUnit.MILLISECONDS)){
Finally, your code can call unlock() even if tryLock() hasn't succeeded. This needs to be fixed.
Make your lock field final static
...
class RequesterThree implements Runnable{
private static final Lock lock = new ReentrantLock();
RequesterThree(){
}
...

Categories