Reputation: 271
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?
Upvotes: 8
Views: 11305
Reputation: 695
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();
}
}
}
Upvotes: 0
Reputation: 1990
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()
Upvotes: 4
Reputation: 5479
use a static lock tisynchronize your method. lock classes are inside the java.concurent package
Upvotes: 0
Reputation: 424983
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.
Upvotes: 13
Reputation: 29473
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
Upvotes: 0
Reputation: 1500065
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:
this
, which I would discourage you from doing. (Any other code could synchronize on the same object.)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.
Upvotes: 8