java method prevent from concurrent access - java

How can I prevent from concurrent access. I have code like this
public class MC implements Runnable {
public void run() {
sync();
}
public static void main(String p[]){
MC mc = new MC();
MC mc2 = new MC();
MC mc3 = new MC();
MC mc4 = new MC();
Thread t = new Thread(mc);
t.start();
Thread t2 = new Thread(mc2);
t2.start();
Thread t3 = new Thread(mc3);
t3.start();
Thread t4 = new Thread(mc4);
t4.start();
}
private synchronized void sync(){
try {
System.out.println(System.currentTimeMillis());
Thread.sleep(10000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
and I am getting output like this
1307082622317
1307082622317
1307082622317
1307082622317
BUILD SUCCESSFUL (total time: 11 seconds)
any advice?

make your method static:
private static synchronized void sync();
your method as coded is synchronized on the instance, but each thread has its own instance, so there's no synchronization.
static methods are synchronized on the Class object, of which there is only one per class, so all instances will synchronize on static methods.

You've got four separate MC objects. Typically running an instance method on those (sync), they shouldn't interfere with each other. You can use a synchronized block to make sure only one runs at a time, but you need to consider what to synchronize on:
If you synchronize on a separate object per instance, that would stop two threads from running the code for the same object. That's effectively what you've got now, but you're implicitly synchronizing on this, which I would discourage you from doing. (Any other code could synchronize on the same object.)
If you synchronize on an object that all the instances know about (e.g. via a static variable) then that would only let one thread run the code at all.
It sounds like you want the latter approach, but it doesn't sound like great design to me. If you really want to implement it that way, you'd use:
public class MC implements Runnable {
private static readonly Object lock = new Object();
...
private void sync() {
synchronized (lock) {
try {
System.out.println(System.currentTimeMillis());
Thread.sleep(10000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
}
Keeping sync as a synchronized method but making it static would also work, but again you'd be locking on a publicly visible object (MC.class) which I generally discourage.

For the desired functionality, you can make the sync function static. I don't talk about the goodness of design. It just do it the way you like!
private static synchronized void sync()

You are instantiating four objects, and sychronized is on different monitor. Either make sync static so that the actual class will be the monitor, or when you instantiate, pass same monitor object to all four, then sync on it

use a static lock tisynchronize your method. lock classes are inside the java.concurent package

Hi u are creating new instances of ur class MC, synchronized method guarantees single access for one instance if it is not static method.
I would suggest u have a private static variable say Integer lock, and then synchronize on it:
private void sync()
{
synchronized (lock)
{
try {
System.out.println(System.currentTimeMillis());
Thread.sleep(10000);
} catch (InterruptedException ex){
ex.printStackTrace();
}
}
}

Related

sleep() method behavior in synchronize block [duplicate]

This question already has answers here:
Synchronized method does not work as expected
(5 answers)
Closed 5 years ago.
class ThreadRunnable implements Runnable{
synchronized public void run(){
System.out.println("In Runnable implemented class");
try {
Thread.sleep(60000);
System.out.println("sleeping over");
System.out.println(System.currentTimeMillis());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public class Sample {
public static void main(String [] args){
ThreadRunnable tr = new ThreadRunnable();
Thread t1 = new Thread(tr);
Thread t2 = new Thread(new ThreadRunnable());
t1.start();
t2.start();
}
}
As its in synchronize method, t2 thread should print the SOP after t1, but both the threads print the SOP simultaneously. Can anyone tell me why?
A synchronized method implicitly synchronizes on this. In your case the instance of ThreadRunnable.
But each thread has its own instance so they use two different monitors.
You have several options to solve your issue such as:
use a private static final Object lock = new Object(); as a monitor with a synchronized block.
or more simply Thread t2 = new Thread(tr);
You are creating two instances of your class.
synchronized prevents that different methods invoke the method on the same method in parallel.
It doesn't prevent calling methods in parallel on different objects!
There is no mutual exclusion. Both of the objects have their own separate monitors that they acquire at synchronized, so they both run at the same time.
If you want to see a difference, pass tr to your second thread as well. Then you have 2 threads sharing 1 object (and one lock).

Why not synchronize run method java?

I'm doing a short course about Threads in Java, in one of my homeworks they asked me: ¿Why you don't should be synchronize the run method? show an example.
I searched about it, and that i think is use synchronized for a run method is not useful, at least commonly. Because the people don't call the run method manually, so the synchronized effect isn't visible creating multiple instances of a object with synchronized run.
So, i would like know if exist another reason or if i'm wrong.
Syncrhonizing the run() method of a Runnable is completely pointless unless you want to share the Runnable among multiple threads and you want to serialize the execution of those threads. Which is basically a contradiction in terms.
If the run method of a Runnable were synchronized, then either
a) you have many runnables (in which case, no need to synchronise, as each one is called on a different object), or else
b) you have one runnable being called in many threads - but then they clearly won't run in parallel -- thus defeating the purpose of having multiple threads!
You may synchronize on run method, nothing wrong with it. I think the reasons behind this advice should be explained to you by the instructor of course.
We need synchronization when there are shared resources (between threads).
Synchronizing on a method is same as synchronizing on this which will block other method calls.
As a counter example, a poor man's Future implementation;
public class SynchronizedRun {
static abstract class Future<T> implements Runnable{
private T value;
public synchronized T getValue(){
return value;
}
protected void setValue(T val){
value = val;
}
}
public static void main(String[] args) {
Future<Integer> longRunningJob = new Future<Integer> (){
#Override
synchronized public void run() {
try {
Thread.sleep(5000);
setValue(42);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
new Thread(longRunningJob).start();
System.out.println("getting results");
System.out.println("result = " + longRunningJob.getValue());
}
}

Java lock objects in one class

I am trying to learn threading, and regarding the following example
public class LockExample {
private Lock lockone = new ReentrantLock();
public void method1() {
lockone.lock();
try {
// do something
} finally {
lockone.unlock();
}
}
public void method2() {
lockone.lock();
try {
// do something
} finally {
lockone.unlock();
}
}
}
does it mean that if we lock method1 and method2 using the same lock, say thread A and B can not access method1 or method2at the same time. But if we lock method1 and method2using different locks lockone and locktwo, then threadA can access method1, at the same time thread Bcan access method2?
why don't we lock each method separately instead of putting them in one lock?
public class LockExample {
private Lock lockone = new ReentrantLock();
public void method1() {
lockone.lock();
try {
// do something
} // wrap the two methods in one lock?
}
public void method2() {
try {
// do something
} finally {
lockone.unlock();
}
}
}
}
does it mean that if we lock method1 and method2 using the same lock, say thread A and B can not access method1 or method2at the same time. But if we lock method1 and method2using different locks lockone and locktwo, then threadA can access method1, at the same time thread Bcan access method2?
Yes, if method1 and method2 using the same lock, then thread A and B cannot access method1 or method 2 at same time. But if methods using different locks, then thread A and B will not be able to access same methods, but accessing different methods will work. That is, thread A and B can't access same method1, or same method2. But while thread A accessing method1, thread B can access method2.
why don't we lock each method separately instead of putting them in one lock?
If you want any threads to block method 2 from accessing, till first thread has not finished access / executtion of method1 and method2, then given code sample is correct.
Example:
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Main implements Runnable {
private Lock lock = new ReentrantLock();
public void method1() throws InterruptedException {
System.out.println(Thread.currentThread().getName() + " entered method1.");
Thread.sleep(1000);
lock.lock();
System.out.println(Thread.currentThread().getName() + " ackquired lock.");
Thread.sleep(1000);
}
public void method2() {
System.out.println(Thread.currentThread().getName() + " entered method2.");
lock.unlock();
System.out.println(Thread.currentThread().getName() + " released lock.");
}
public void run() {
try{
method1();
}catch(Exception e){
e.printStackTrace();
}finally{
method2();
}
}
public static void main(String [] args) {
Runnable runnable = new Main();
new Thread(runnable, "ThreadA").start();
new Thread(runnable, "ThreadB").start();
}
}
If you use the same lock for both methods, then if thread-1 is executing method-1 (i.e, after acquiring the lock), then no other thread can execute method-1 as well as method-2.
If you use 2 different locks for 2 methods, then if thread-1 and thread-2 are executing method-1 and method-2 by acquiring lock on lock-1 and lock-2 respectively, then other threads can execute method-1 if thread-1 releases the lock and method-2 if thread-2 releases the lock.
why don't we, or can we make method1 and 2 into one critical section by only acquiring the lock in methos1, and releasing the lock after method2?
Because it's bad design.
The office where I work has hundreds of thousands of lines of Java code to maintain. Some of it's been around for as long as ten years, and developers have been coming and going and working in that code all that time. Adherence to strict style rules and strict conventions is an important part of how we keep it all safe and sane and mostly bug-free.
If we use a ReentrantLock, we use always use it just how you used it in your first example:
lockone.lock();
try {
// do something
} finally {
lockone.unlock();
}
If there's a methodOne, and a methodTwo, and there's a need to call them both atomically, then we write it like this:
private methodOne(...) { ... }
private methodTow(...) { ... }
public callMethodOneAndMethodTwo(...) {
lockOneTwo.lock();
try {
methodOne(...);
methodTwo(...);
} finally {
lockOneTwo.unlock();
}
This way of managing the lock guarantees that no thread can ever fail to unlock the lock after it's done what it needs to do. It guarantees that no other function in any other package can call methodOne() without subsequently calling methodTwo(). It guarantees that no such function can call methodTwo() without first calling methodOne(). It's easier to understand, and it's easier to maintain.

Java - synchronizing static methods

Here is a piece of text I found at this link.
"Avoid lock on static methods
The worst solution is to put the "synchronized" keywords on the static
methods, which means it will lock on all instances of this class."
Why would synchronizing a static method lock all instances of the class? Shouldn't it just lock the Class?
To understand this, the easiest way is to compare how lock works against instance method and static method.
Let's say you have class Test.java, which has two methods as follow.
public class Test{
public synchronized void instanceMethod(){
}
public synchronized static void staticMethod(){
}
}
Meanwhile, there are two instances of class Test, testA and testB. And also there are two thread tA and tB trying to access class Test in parallel.
locking on instanceMethod:
When tA gets the lock on instanceMethod of testA, tB cannot access the the same method in testA, however tB is still free to invoke instanceMethod in testB. Because the synchronization against instanceMethod is instance level locking
locking on staticMethod:
However, when tA gets the lock on staticMethod, the lock has nothing to do with testA or testB, since synchronization on static method is a class level locking. Which means tB cannot access staticMethod at all until tA release the lock
Actually a lock on a static method of class Foo, is the same as putting a lock on Foo.class (which is the only instance):
public static void doSomething()
{
synchronized(Foo.class)
{
// ...
}
}
Here's my test code that shows that you're right and the article is a bit over-cautious:
class Y {
static synchronized void staticSleep() {
System.out.println("Start static sleep");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
System.out.println("End static sleep");
}
synchronized void instanceSleep() {
System.out.println("Start instance sleep");
try {
Thread.sleep(200);
} catch (InterruptedException e) {
}
System.out.println("End instance sleep");
}
}
public class X {
public static void main(String[] args) {
for (int i = 0; i < 2; ++i) {
new Thread(new Runnable() {
public void run() {
Y.staticSleep();
}
}).start();
}
for (int i = 0; i < 10; ++i) {
new Thread(new Runnable() {
public void run() {
new Y().instanceSleep();
}
}).start();
}
}
}
Prints:
Start instance sleep
Start instance sleep
Start instance sleep
Start instance sleep
Start instance sleep
Start static sleep
Start instance sleep
Start instance sleep
Start instance sleep
Start instance sleep
Start instance sleep
End instance sleep
End instance sleep
End instance sleep
End instance sleep
End instance sleep
End instance sleep
End instance sleep
End instance sleep
End instance sleep
End instance sleep
End static sleep
Start static sleep
End static sleep
So the static synchronized has no bearing on the synchronized methods on the instances...
Of course if static synchronised methods are used throughout the system, then you can expect them to have the most impact on the throughput of a multithreaded systems, so use them at your peril...
You are right — the actual lock is on the Class instance itself, not on any instance of the class (let alone all instances) — but I think you're interpreting the linked page too literally. It itself uses the phrase "a static lock (a Class lock)", so clearly its author is aware of how the locking works. But if you have many instances in different threads that are all using synchronized static methods, then those instances will all lock each other out. The synchronized static methods won't cause blocking of synchronized instance methods, but the problem is there regardless.
It doesn't say 'lock all instances of the class'. It says 'lock on all instances of the class. It's poorly worded, indeed incorrect, but it doesn't it say what you said it said.
A synchronized method acquires a monitor (§17.1) before it executes. For a class (static) method, the monitor associated with the Class object for the method's class is used. For an instance method, the monitor associated with this (the object for which the method was invoked) is used.
http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.4.3.6

Why is this thread allowing another one to access its synchronized method?

I have the following codes. I expected one thread to execute its synchronized method completely and then allow another one to access the same method. However, this is not the case.
public class Threads {
/**
* #param args
*/
public static void main(String[] args) {
//Thread Th = new Threads();
Thread th = new Thread (new thread1 ());
th.start();
Thread th1 = new Thread (new thread1 ());
th1.start();
}
}
class thread1 implements Runnable{
String name = "vimal";
public void run() {
System.out.println("Runnable "+this.name);
setNAme("Manish");
}
public synchronized void setNAme(String name){
try {
System.out.println("Thread "+Thread.currentThread().getName());
wait(1000);
this.name = name;
System.out.println("Name "+this.name);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I have one output as
Runnable vimal
Thread Thread-0
Runnable vimal
Thread Thread-1
Name Manish
Name Manish
What is the use of synchronized here and how do I make my method to run completely before another accesses it?
synchronized has no effect here because you are not synchronizing on the same object in both cases. When applied to an instance method, the synchronized keyword causes the method to be synchronized on this. So in each case you are synchronizing on the instance of thread1, and there are two of those.
The more interesting test would be when you run the same instance of thread1 in two threads simultaneously. In that case, calling wait(1000) is a very bad thing to do because (as documented) it releases the lock on this. You want to use Thread.sleep(1000) instead in your code.
If you need to have two instances of thread1, you need to synchronize on some shared object, possibly like this:
private static final Object lockObject = new Object();
public void setName(String newName) {
synchronized(lockObject) {
doSetName(newName);
}
}
You will have to remove the call to wait(1000). It looks like what you actually want is a call to Thread.sleep(1000), if you simply want to pause the current thread, this does not release ownership of any monitors.
From the javadoc for Object.wait().
This method causes the current thread (call it T) to place itself in
the wait set for this object and then to relinquish any and all
synchronization claims on this object. Thread T becomes disabled for
thread scheduling purposes and lies dormant until one of four things
happens:
Some other thread invokes the notify method for this object and thread T happens to be arbitrarily chosen as the thread to be
awakened.
Some other thread invokes the notifyAll method for this object.
Some other thread interrupts thread T.
The specified amount of real time has elapsed, more or less. If timeout is zero, however, then real time is not taken into
consideration and the thread simply waits until notified.
The thread T is then removed from the wait set for this object and
re-enabled for thread scheduling. It then competes in the usual manner
with other threads for the right to synchronize on the object; once it
has gained control of the object, all its synchronization claims on
the object are restored to the status quo ante - that is, to the
situation as of the time that the wait method was invoked. Thread T
then returns from the invocation of the wait method. Thus, on return
from the wait method, the synchronization state of the object and of
thread T is exactly as it was when the wait method was invoked.
UPDATE: As has been mentioned in other answers, you are not synchronizing on the same object. Once you do, you will still suffer the same output, due to the issue I have mentioned. You will need to fix both for your desired results.
The output is correct, you are creating to independent threads that do not share any data. Thus both threads start with first string, and after some time, the string is changed and printed.
You're creating 2 thread1 objects. They each have their own setNAme method. Synchronized methods only synchronize on the object, not the class. Unless the method is static.
You have two Threads here with independent name variables and independent monitors, so each Thread is only accessing its own members. If you want to have the threads interact with each other you'll have to implement such an interaction.
you are creating two separate thread1 objects and running them. Each thread has it's own copy of the name variable as well as the setName function. Make them both static and you will see the effects of synchronization.
You are locking on two different instance of the objects where you dont need any synchronization at all. You need to synchronize only if you are working on a shared data. I think you meant to write a test like the below.
If you test this, you will realize that the second thread will wait until the first thread is completed with the synchronized method. Then take out the synchronized word and you will see both threads are executing at the same time.
public class SynchronizeTest {
public static void main(String[] args) {
Data data = new Data();
Thread task1 = new Thread(new UpdateTask(data));
task1.start();
Thread task2 = new Thread(new UpdateTask(data));
task2.start();
}
}
class UpdateTask implements Runnable {
private Data data;
public UpdateTask(Data data) {
this.data = data;
}
public void run() {
try {
data.updateData();
} catch (Exception e) {
e.printStackTrace();
}
}
}
class Data {
public synchronized void updateData() throws InterruptedException {
for (int i = 0; i < 5; i++) {
Thread.sleep(5000);
System.out.println(i);
}
}
}

Categories