Class level lock for static variables in java - java

If i don't use any setters/getters in my java class X. When a thread A has class level lock of my class X. Can another thread B change my static variable directly ??
public class X {
Integer static_variable = 10;
public static void doNothing {
/* Do Nothing */
}
}
Lets say thread A has class level lock now. Can i do X.static_variable = 11 from another thread B?
I was writing a code to get deadlock in java.
public class A implements Runnable {
public static Integer as = 5;
static A a = new A();
static B b = new B();
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
Thread thread1 = new Thread(a);
Thread thread2 = new Thread(b);
thread1.setName("First");
thread2.setName("Second");
thread1.start();
thread2.start();
}
public void run() {
runme();
}
public static synchronized void runme() {
try {
System.out.println(Thread.currentThread().getName() + " has object a's key and waiting");
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + " Woke up from sleep");
System.out.println(Thread.currentThread().getName() + " wants b's Key");
B.bs = 10;
System.out.println(Thread.currentThread().getName() + " over");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class B implements Runnable {
public static Integer bs = 6;
public void run() {
runme();
}
public static synchronized void runme() {
try {
System.out.println(Thread.currentThread().getName() + " has object b's key and waiting");
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + " Woke up from sleep");
System.out.println(Thread.currentThread().getName() + " wants a's Key");
A.as = 10;
System.out.println(Thread.currentThread().getName() + " over");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
But getting below result:
Second has object b's key and waiting
First has object a's key and waiting
First Woke up from sleep
Second Woke up from sleep
Second wants a's Key
Second over
First wants b's Key
First over
Second thread is clearly editing the static variable of class A even when another thread holds the class level lock of class A

Yes you can. Unless you have a synchronized block around the variable changing code. If you don't use synchronization, other threads don't have to acquire the X.class's monitor before changing its static_variable.
Make the field private, and add a setter, make it synchronized, then you will not be able to change the field when another thread holds the lock for X.class

Related

Java: thread able to call a method that is in synchronised block of some other thread

thread t1 is calling test1() method of Test class object ob.
thread t2 is calling test1() method of Test class object ob in synchronized block.
t1 is able to call test1() method of ob even though test1() method call of ob is in synchronised block of thread t2.
The code is given below:
class Test {
void test1() {
while(1 == 1) {
System.out.println(Thread.currentThread().getName() + " test1!");
}
}
void test2() {
while(1 == 1) {
System.out.println(Thread.currentThread().getName() + " test2!");
}
}
}
class NewThread1 implements Runnable {
Thread t;
String name;
Test target;
NewThread1(Test ob, String threadname) {
target = ob;
name = threadname;
t = new Thread(this, name);
}
public void run() {
target.test1();
}
}
class NewThread2 implements Runnable {
Thread t;
String name;
Test target;
NewThread2(Test ob, String threadname) {
target = ob;
name = threadname;
t = new Thread(this, name);
}
public void run() {
synchronized(target) {
target.test1();
}
}
}
class Test1 {
public static void main(String args[]) {
Test ob = new Test();
NewThread1 t1 = new NewThread1(ob, "t1");
NewThread2 t2 = new NewThread2(ob, "t2");
t2.t.start();
t1.t.start();
try {
t1.t.join();
t2.t.join();
} catch(InterruptedException e) {
System.out.println("Main thread interrupted");
}
System.out.println("Main thread exiting");
}
}
Since NewThread1#run() is not synchronized it will not try to get the monitor on the target and it will therefore not be blocked, it can call the method on the target even if another thread holds the monitor of it.
Synchronized can only exclusively lock out other threads if all threads compete against the same monitor with a synchronized section. (It does not matter of you call test1 or test2 the check happens in the synchronize based on the target). What you could do is to make test1 and test2 synchronized methods, then they will try to reserve the monitor of the instance in all cases). Same is not only true for exclusive execution, but also for any memory access guarantees (happens-after) you might want to get out of a synchronized block.
BTW you don’t need different thread classes, if you only use one (the one with the synchronized) it works like expected.
Thread t1 = new NewThread2(ob, "t1");
Thread t2 = new NewThread2(ob, "t2");
However if your scope of locking is narrow, it is much better to localize the locking inside (all) instance methods of the target Test, because then you can never call them with a missing synchronized (and you can switch to other locking primitives without the caller having to know).
void synchronized test1() {
while(1 == 1) {
System.out.println(Thread.currentThread().getName() + " test1!");
}
}
Or
void test1() {
synchronized(this) {
while(1 == 1) {
System.out.println(Thread.currentThread().getName() + " test1!");
}
}
}

Why is it important to make fields private when working with concurrency?

I'm reading Thinking in JAVA (Ed4, by Bruce Eckel), which says:
Note that it’s especially important to make fields private when
working with concurrency; otherwise the synchronized keyword cannot
prevent another task from accessing a field directly, and thus
producing collisions.
I am confused and finally get this demo:
public class SimpleSerial {
public static void main(String[] args) throws IOException {
ShareObject so = new ShareObject();
Thread thread1 = new Thread(new ThreadOperation(so, "add"));
Thread thread2 = new Thread(new ThreadOperation(so, "sub"));
thread1.setDaemon(true);
thread2.setDaemon(true);
thread1.start();
thread2.start();
System.out.println("Press Enter to stop");
System.in.read();
System.out.println("Now, a=" + so.a + " b=" + so.b);
}
}
class ThreadOperation implements Runnable {
private String operation;
private ShareObject so;
public ThreadOperation(ShareObject so, String oper) {
this.operation = oper;
this.so = so;
}
public void run() {
while (true) {
if (operation.equals("add")) {
so.add();
} else {
so.sub();
}
}
}
}
class ShareObject {
int a = 100;
int b = 100;
public synchronized void add() {
++a;
++b;
}
public synchronized void sub() {
--a;
--b;
}
}
Every time the values of a and b are different. So why?
The demo also mentioned if the thread sleep() for short time, i.e., re-write the run() method in ThreadOperation:
public void run() {
while (true) {
if (operation.equals("add")) {
so.add();
} else {
so.sub();
}
try {
TimeUnit.MILLISECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
then values of a and b are the same.
So again, Why? What happens behind sleep()?
With sleep() it becomes probable that the println() executes while the threads are sleeping. The program is still very not thread-safe.
You could fix it by adding a synchronized print() method to SharedObject eg:
public synchronized void print() {
System.out.println("Now, a=" + a + " b=" + b);
}
and calling that on the last line of main instead of the current unsynchronized accesses.

how to implement wait,notify with threadexecutor in java

how to implement wait,notify with threadexecutor in java,Suppose I have two objeccts of threadExecutor and I want to perform wait,notify on that objecct can we implement that.
Here is an Example of using wait notify with ThreadExecutor in Java :
public class ExecutorServiceTest {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(2);
ThreadB threadB = new ThreadB();
ThreadA threadA = new ThreadA(threadB);
executor.execute(threadA);
executor.execute(threadB);
executor.shutdown();
while (!executor.isTerminated());
System.out.println("Finished all threads");
}
static class ThreadA extends Thread {
private final ThreadB waitThread;
public ThreadA(ThreadB waitThread) {
this.waitThread = waitThread;
}
#Override
public void run() {
synchronized (waitThread) {
try {
waitThread.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("B Count Total : " + waitThread.getCount());
for (int i = waitThread.getCount(); i < 200; i++) {
System.out.println("A Counting " + i);
}
}
}
}
static class ThreadB extends Thread {
private int count = 0;
#Override
public void run() {
synchronized (this) {
while (count < 100) {
System.out.println("B Counting " + count);
count++;
}
notify();
}
}
public int getCount() {
return count;
}
}
}
synchronized
keyword is used for exclusive accessing.
To make a method synchronized, simply add the synchronized keyword to its declaration. Then no two invocations of synchronized methods on the same object can interleave with each other.
synchronized statements must specify the object that provides the intrinsic lock:
wait()
tells the calling thread to give up the monitor and go to sleep until some other thread enters the same monitor and calls notify( ).
notify()
wakes up the first thread that called wait() on the same object.

Concurrent Threads

I completed some basic code to assign 2 threads a task. But I have to make 2 versions where one can have both threads invoke the task concurrently, and one where it would never be concurrent. But I'm not even sure which version I have made, let alone how I would identify it.
import java.util.*;
public class Week5
{
static int sharedData = 0;
public static void main(String[] args)
{
atomic myAtomic = new atomic();
Thread thread1 = new Thread(myAtomic);
thread1.setName("thread 1");
Thread thread2 = new Thread(myAtomic);
thread2.setName("thread 2");
thread1.start();
thread2.start();
try
{
thread1.join();
thread2.join();
}
catch(InterruptedException e)
{
System.out.println("Thread " + Thread.currentThread().getName() + "was interrupted");
}
System.out.println("sharedData = " + sharedData);
System.out.println("Exiting Main function from: " + Thread.currentThread().getName());
}
public static class atomic implements Runnable
{
public synchronized void run()
{
System.out.println("Starting 'Atomic' Function from: " + Thread.currentThread().getName());
sharedData = sharedData + 1;
System.out.println("Exiting 'Run' function from: " + Thread.currentThread().getName());
}
}
}
Your threads can never run the same task concurrently, because the run() method is synchronized, meaning only one thread can enter at a time for the same object. If it were not synchronized, both threads could potentially execute it simultaneously.

A good small example to demonstrate wait() and notify() method in java

Can anybody please provide me a good small example demonstrate wait() and notify() functionality in java. I've tried with the below piece of code but it's not showing what i expected.
public class WaitDemo {
int i = 10;
int display() {
System.out.println("Lexmark");
i++;
return i;
}
}
public class ClassDemo1 extends Thread {
private WaitDemo wd = new WaitDemo();
public static void main(String[] args) {
ClassDemo1 cd1 = new ClassDemo1();
ClassDemo1 cd2 = new ClassDemo1();
cd1.setName("Europe");
cd2.setName("America");
cd1.start();
cd2.start();
}
synchronized void display() {
System.out.println("Hello");
notifyAll();
}
public void run() {
synchronized (this) {
try {
{
notify();
System.out.println("The thread is " + currentThread().getName());
wait();
System.out.println("The value is " + wd.display());
}
} catch (InterruptedException e) {
}
}
}
}
The issue is that the method in the class WaitDemo is not getting executed and as per my idea the SOP after wait() should execute. Please help me out on this.
You've got two levels of braces { in your try block. If you remove the inner set (which doesn't appear to do anything), does that fix the problem?
There are several examples around, all of which demonstrate the use. The last link is a set of results that can help you out. If you need more specific things, let me know what it is that your app is trying to do, and I can try to find examples that are more specific to your situation.
http://www.javamex.com/tutorials/wait_notify_how_to.shtml
http://www.java-samples.com/showtutorial.php?tutorialid=306
http://www.coderanch.com/t/234235/threads/java/Wait-Example
https://www.google.com/search?q=wait%28%29+example+java&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:en-US:official&client=firefox-a
Below is an example of wait & notify in the Object class. The customer is trying to withdraw money of value 2000 but the account is having only 1000 so it has to wait for the deposit. Once the deposit is made, then the customer will be able to withdraw the amount. Until the deposit is made, the customer will be waiting.
class Cust {
private int totalAmount = 1000;
public synchronized void withdrawal(int amount) {
System.out.println("Total amount " + totalAmount + " withdrawing amount " + amount);
while (this.totalAmount < amount) {
System.out.println("not enough amount..waiting for deposit..");
try { wait(); } catch (Exception e) {}
}
this.totalAmount -= amount;
System.out.println("Withdrawal successful.. Remaining balance is "+totalAmount);
}
public synchronized void deposit(int amount){
System.out.println("Depositing amount "+amount);
this.totalAmount += amount;
System.out.println("deposit completed...and Now totalAmount is " + this.totalAmount);
notify();
}
}
class Depo implements Runnable {
Cust c; int depo;
Depo(Cust c, int depo){
this.c = c;
this.depo = depo;
}
#Override
public void run() {
c.deposit(depo);
}
}
class Withdrawal implements Runnable {
Cust c; int with;
Withdrawal(Cust c, int with){
this.c = c;
this.with = with;
}
#Override
public void run() {
c.withdrawal(with);
}
}
public class ObjectWaitExample {
public static void main(String[] args) {
Cust c = new Cust();
Thread w = new Thread(new Withdrawal(c, 2000));
Thread d1 = new Thread(new Depo(c, 50));
Thread d2 = new Thread(new Depo(c, 150));
Thread d3 = new Thread(new Depo(c, 900));
w.start();
d1.start();
d2.start();
d3.start();
}
}
I created two threads one for printing odd numbers (OddThread) and another for even numbers (EvenThread). Inside the run method of each of the threads I used the shared object of class Print to call printOdd() and printEven() for the Odd and EvenThread respectively. I made the shared object of Print static so that only one copy is made. Now synchronizing on the Print object I used a Boolean flag such that when the odd thread printed an odd number it will be sent into the waiting state and the at the same time notifying the even thread to execute. The logic is written in such a way that the odd thread will always print the odd number first no matter what, as the flag is set to false initially preventing the even thread to execute and sending it to a waiting state.
package com.amardeep.test;
public class ThreadDemo {
// Shared object
static Print print = new Print();
public static void main(String[] args) {
new Thread(new OddThread()).start();
new Thread(new EvenThread()).start();
}
}
class EvenThread implements Runnable {
#Override
public void run() {
ThreadDemo.print.printEven();
}
}
class OddThread implements Runnable {
#Override
public void run() {
ThreadDemo.print.printOdd();
}
}
class Print {
public volatile boolean flag = false;
public synchronized void printEven() {
for (int i = 1; i <= 10; i++) {
if (!flag) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
if (i % 2 == 0) {
System.out.println("from even " + i);
flag = false;
notifyAll();
}
}
}
}
public synchronized void printOdd() {
for (int i = 1; i <= 10; i++) {
if (flag) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
if (i % 2 != 0) {
System.out.println("from odd " + i);
flag = true;
notifyAll();
}
}
}
}
}
output:-
from odd 1
from even 2
from odd 3
from even 4
from odd 5
from even 6
from odd 7
from even 8
from odd 9
from even 10
Your problem is that you are creating two instances of the Thread class. Thus when the wait() is called, it is on two different instances, neither of which has another thread that is in contention for your monitor, nor is there another thread to call notifyAll() to wake the thread from its wait state.
Thus each thread you have started will wait forever (or until interrupted for some other reason).
You want to have multiple threads accessing the same monitor, so start by trying to code something in which the code in question is not actually a thread, but is simply being used by a thread.
#normalocity has already provided links to multiple examples.
I just updated this answer to include an SCCE.
The workers call pauseIfNeeded on the WorkerPauseManager. If the manager is paused when the worker thread calls pauseIfNeeded(), we call wait(), which tells the calling thread to wait until a different thread calls notify() or notifyAll() on the object being waited on. This happens when the Swing Event Dispatch Thread calls play() on the manager, which in turn calls notifyAll().
Note that you must have a synchronized lock on the object you are calling wait() or notify() on. Since the methods in WorkerPauseManager are synchronized, all the synchronized methods are getting a synchronized lock on the WorkerPauseManager itself.
import javax.swing.*;
import java.awt.event.ActionEvent;
/**
* #author sbarnum
*/
public class WorkerPauseManagerTest {
public static void main(String[] args) {
final WorkerPauseManager pauseManager = new WorkerPauseManager();
new Worker("Worker 1", pauseManager).start();
new Worker("Worker 2", pauseManager).start();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JToggleButton playPauseButton = new JToggleButton(new AbstractAction("Pause") {
public void actionPerformed(final ActionEvent e) {
JToggleButton source = (JToggleButton) e.getSource();
if (source.isSelected()) {
pauseManager.start();
source.setText("Pause");
} else {
pauseManager.pause();
source.setText("Play");
}
}
});
playPauseButton.setSelected(true); // already running
JOptionPane.showMessageDialog(null, playPauseButton, "WorkerPauseManager Demo", JOptionPane.PLAIN_MESSAGE);
System.exit(0);
}
});
}
private static class Worker extends Thread {
final String name;
final WorkerPauseManager pauseManager;
public Worker(final String name, final WorkerPauseManager pauseManager) {
this.name = name;
this.pauseManager = pauseManager;
}
#Override
public void run() {
while (!Thread.interrupted()) {
try {
pauseManager.pauseIfNeeded();
System.out.println(name + " is running");
Thread.sleep(1000L);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
public static final class WorkerPauseManager {
private boolean paused;
public synchronized void pauseIfNeeded() throws InterruptedException {
if (paused) wait();
}
public synchronized void pause() {
this.paused = true;
}
public synchronized void start() {
this.paused = false;
notifyAll();
}
}
}
What wait method does is , when some thread executed a synchronized block by locking some object (we call that object is "a") , then inside that synchronized block when the thread executed the wait method of object "a" like this
A a = new A (); // some class object call "a"
synchronized (a){
a.wait ();//exceptions must be handled
}
Then the a object will release and the thread has to go to the wait state until it has been release from that state.
and anothet thread now can use the a object beacause its a release object. so if another thread locked that object and it executed the notify method from that object like
a.notify ()
Then one of a thread of the threads that went to wait state by object "a" can be released from the wait state. Other wise when call the notifyAll then the all the thread objects will release from that state.
/*
* the below program is like
* tread t1 will first run , and it comes to "notify()" method
* there are no threds waiting bcoz this is the first thread.
* so it will not invoke any other threads. next step is "wait()" method
*will be called and the thread t1 in waiting state. next stament
* "System.out.println("The value is ..."+wd.display());" will not be executed
* because thread t1 is in waiting state.
*
* thread t2 will run ,and it comes to "notify()" method ,there is already
* thread t1 is in waiting state ,then it will be invoked.now thread t1 will
* continue execution and it prints the statement "System.out.println("The value is ..."+wd.display())"
* and thread t2 will be in waiting state now.
*
* if you uncomment "notifyAll()" method then, after t1 thread completes its execution
*then immediately "notifyAll()" method will be called,by that time thread t2 is
* already in waiting state , then thread t2 will be invoked and continues execution.
*or
* if any other threadds are in waiting state all those threads will be invoked.
*/
package threadsex;
/**
*
* #author MaheshM
*/
/**
* #param args the command line arguments
*/
public class WaitNotifyNotifyAllDemo implements Runnable {
WaitDemo wd = new WaitDemo();
public static void main(String[] args) {
WaitNotifyNotifyAllDemo cd1 = new WaitNotifyNotifyAllDemo();
Thread t1 = new Thread(cd1);
t1.setName("mahi1");
Thread t2 = new Thread(cd1);
t2.setName("mahi2");
t1.start();
t2.start();
}
#Override
public void run() {
synchronized (this) {
try {
System.out.println("The thread is=" +
Thread.currentThread().getName());
notify();
wait();
System.out.println("The value is ..." + wd.display());
// notifyAll();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
}

Categories