Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么我的同步方法可以锁定不同的对象?_Java_Concurrency_Thread Safety_Synchronized - Fatal编程技术网

Java 为什么我的同步方法可以锁定不同的对象?

Java 为什么我的同步方法可以锁定不同的对象?,java,concurrency,thread-safety,synchronized,Java,Concurrency,Thread Safety,Synchronized,我现在正在学习Java并发。我遇到了这样一段代码: package pac1; import java.util.*; import java.util.concurrent.*; class A1 { public void f() { synchronized (this) { for (int i = 0; i < 5; i++) System.out.println("f()");

我现在正在学习Java并发。我遇到了这样一段代码:

package pac1;

import java.util.*;
import java.util.concurrent.*;

class A1 {
    public void f() {
        synchronized (this) {
            for (int i = 0; i < 5; i++)
                System.out.println("f()");
        }
    }
}

class B1 {
    public void g() {
        synchronized (this) {
            for (int i = 0; i < 5; i++)
                System.out.println("g()");
        }
    }
}

class C1 {
    public void p() {
        synchronized (this) {
            for (int i = 0; i < 5; i++)
                System.out.println("p()");
        }
    }

}

public class V {
    public static void main(String[] args) {
        A1 a = new A1();
        B1 b = new B1();
        C1 c = new C1();
        new Thread() {
            public void run() {
                a.f();
            }
        }.start();
        new Thread() {
            public void run() {
                c.p();
            }
        }.start();
        b.g();
    }

}
顺便说一句,使用Lock的结果是相同的:

package pac1;

import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class A {
    Lock lock = new ReentrantLock();

    public void f() {
        lock.lock();
        try {
            for (int i = 0; i < 5; i++)
                System.out.println("f()");
        } finally {
            lock.unlock();
        }
    }
}

class B {
    Lock lock = new ReentrantLock();

    public void g() {
        lock.lock();
        try {
            for (int i = 0; i < 5; i++)
                System.out.println("g()");
        } finally {
            lock.unlock();
        }
    }
}

class C {
    Lock lock = new ReentrantLock();

    public void p() {
        lock.lock();
        try {
            for (int i = 0; i < 5; i++)
                System.out.println("p()");
        } finally {
            lock.unlock();
        }
    }
}

public class Ex16 {

    public static void main(String[] args) {
        A a = new A();
        B b = new B();
        C c = new C();
        new Thread() {
            public void run() {
                a.f();
            }
        }.start();
        new Thread() {
            public void run() {
                c.p();
            }
        }.start();
        b.g();
    }

}
pac1包;
导入java.util.*;
导入java.util.concurrent.*;
导入java.util.concurrent.locks.Lock;
导入java.util.concurrent.locks.ReentrantLock;
甲级{
Lock Lock=新的可重入锁();
公共空间f(){
lock.lock();
试一试{
对于(int i=0;i<5;i++)
System.out.println(“f()”);
}最后{
lock.unlock();
}
}
}
B类{
Lock Lock=新的可重入锁();
公共空间g(){
lock.lock();
试一试{
对于(int i=0;i<5;i++)
System.out.println(“g()”);
}最后{
lock.unlock();
}
}
}
C类{
Lock Lock=新的可重入锁();
公共空间p(){
lock.lock();
试一试{
对于(int i=0;i<5;i++)
System.out.println(“p()”);
}最后{
lock.unlock();
}
}
}
公共类Ex16{
公共静态void main(字符串[]args){
A=新的A();
B=新的B();
C=新的C();
新线程(){
公开募捐{
a、 f();
}
}.start();
新线程(){
公开募捐{
c、 p();
}
}.start();
b、 g();
}
}

实际上,循环不够长,因此允许线程按启动顺序完成。为了确保线程不会干扰,您可以尝试以下方法之一:

  • 使循环运行更长时间,例如,1000次迭代就足够了:

    已同步(此){
    对于(int i=0;i<1000;i++)
    System.out.println(“f()”);
    }

  • 暂停循环中的线程,但确保为每个循环设置不同的间隔:

    已同步(此){
    对于(int i=0;i<5;i++){
    System.out.println(“p()”);
    试一试{
    睡眠(3000);
    }捕获(最终中断例外){
    //吞咽
    }
    }
    }


长话短说:这些锁实际上不会相互干扰。

这里不需要锁或同步。Sychronized用于锁定对共享可变状态的访问。您一开始没有任何共享的可变状态


这里有3个线程,由于上下文切换,没有人能够预测这些线程的运行顺序。我看没问题

试着打印更多的东西。我怀疑Java在设置第二个线程时完成了第一个线程的方法的运行,然后在第一个线程真正开始运行之前,它完成了主方法的运行,所以您可以按1,3,2的顺序打印它们。我敢打赌,如果你每做1000个,它们就会混在一起。你怎么会认为它们互相干扰?在每次迭代中添加对Thread.sleep(500)的调用。
package pac1;

import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class A {
    Lock lock = new ReentrantLock();

    public void f() {
        lock.lock();
        try {
            for (int i = 0; i < 5; i++)
                System.out.println("f()");
        } finally {
            lock.unlock();
        }
    }
}

class B {
    Lock lock = new ReentrantLock();

    public void g() {
        lock.lock();
        try {
            for (int i = 0; i < 5; i++)
                System.out.println("g()");
        } finally {
            lock.unlock();
        }
    }
}

class C {
    Lock lock = new ReentrantLock();

    public void p() {
        lock.lock();
        try {
            for (int i = 0; i < 5; i++)
                System.out.println("p()");
        } finally {
            lock.unlock();
        }
    }
}

public class Ex16 {

    public static void main(String[] args) {
        A a = new A();
        B b = new B();
        C c = new C();
        new Thread() {
            public void run() {
                a.f();
            }
        }.start();
        new Thread() {
            public void run() {
                c.p();
            }
        }.start();
        b.g();
    }

}