java方法防止并发访问
如何防止并发访问。我有这样的代码java方法防止并发访问,java,multithreading,Java,Multithreading,如何防止并发访问。我有这样的代码 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();
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();
}
}
}
1307082622317
1307082622317
1307082622317
1307082622317
BUILD SUCCESSFUL (total time: 11 seconds)
我得到这样的输出
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();
}
}
}
1307082622317
1307082622317
1307082622317
1307082622317
BUILD SUCCESSFUL (total time: 11 seconds)
有什么建议吗?您有四个单独的MC对象。通常在这些(
sync
)上运行实例方法,它们不应该相互干扰。您可以使用<代码>同步块,以确保每次只运行一个,但您需要考虑同步:
- 如果对每个实例在一个单独的对象上进行同步,这将阻止两个线程为同一个对象运行代码。这实际上就是您现在所拥有的,但是您正在隐式地同步
,我不鼓励您这样做。(任何其他代码都可以在同一对象上同步。)这个
- 如果在所有实例都知道的对象上进行同步(例如,通过静态变量),那么只允许一个线程运行代码
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();
}
}
}
}
保持
sync
作为一种同步方法,但使其保持静态也会起作用,但同样,您会锁定一个公共可见的对象(MC.class
),我通常不鼓励这种做法。您正在实例化四个对象,而sychronized
在不同的监视器上。使sync
静态,使实际类成为监视器,或者在实例化时,将相同的监视器对象传递给所有四个对象,然后在其上进行同步使方法静态:
private static synchronized void sync();
编码的方法在实例上是同步的,但每个线程都有自己的实例,因此没有同步
静态方法在类对象上同步,每个类只有一个静态方法,因此所有实例都将在静态方法上同步。使用静态锁来同步方法。锁类位于java.concurent包中对于所需的功能,可以将sync函数设置为静态。我不谈论设计的好处。就按你喜欢的方式做吧
private static synchronized void sync()
Hi-u正在创建ur类MC的新实例,synchronized方法保证一个实例的单次访问,如果它不是静态方法的话 我建议您使用一个私有静态变量,比如Integer lock,然后对其进行同步: 私有void sync() { 已同步(锁定) { }
}期望的输出是什么?你想要达到什么?呵欠-看看我的答案:只需制定方法static@Bohemian:正如我在回答的最后特别指出的,这会起作用,但这意味着锁定一个公共可见的对象。这不是一个好主意,IMO-我喜欢能够对我的代码进行推理,因为我知道没有其他东西可以锁定相同的对象。@Jon_Skeet:这很公平,但坦率地说,整个类“设计得不太好”,仅用于演示目的,所以这个快速修复程序回答了他的“wtf正在进行”问题。@Bohemian:如果你想,你可以选择快速修复,但我宁愿质疑设计,同时提及最佳实践。我认为OP会通过这种方式学到更多,即使你只是打哈欠……这就足够了:同步(MC.class){