Java 为什么我的同步方法可以锁定不同的对象?
我现在正在学习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()");
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();
}
}