Java同步和线程 import java.util.Random; 甲级公共课{ int a=0,b=10; Random rand=新的Random(); 公共同步的void add(){ 如果(a >代码> b>代码>中表示两个数,在其他上下文中,变量 a < /> >和 b>代码>引用类A和类B 的实例。将A类字段转换为其他字段,如number1和number2 “假设一个代码块被声明为已同步(x)。进入该代码块的第一个线程获得对象的锁…”对不起,但是代码块之外的代码呢?假设您有一个方法public void f(){val++;synchronized(this){anotherVal++;}}。在这种情况下,如何说“首先进入块的线程获得对象x的锁”?(变量val仍然可以由另一个线程修改,对吗?) import java.util.Random; public class ClassA{ int a = 0, b = 10; Random rand = new Random(); public synchronized void add(){ if (a < 10){ a++; b--; }; } public synchronized void subtract(){ if (b < 10){ b++; a--; } } public synchronized boolean check(){ return a + b == 10; } public static void main(String args[]){ ClassA a = new ClassA(); B ba = new B(a); B bb = new B(a); //notice these two threads are not associated with the object a! Thread t11 = new Thread(bb); Thread t22 = new Thread(ba); t11.start(); t22.start(); } } class B implements Runnable{ ClassA a; B(ClassA a){ this.a = a; } @Override public void run(){ while (a.check()){ if (a.rand.nextInt(2) == 1) a.subtract(); else a.add(); } System.out.print("Out of sync"); } }
我试图更好地理解java多线程。因此,我知道俗话说,只有一个线程可以访问一个对象实例,从而调用该实例的方法(例如,在本例中,类Java同步和线程 import java.util.Random; 甲级公共课{ int a=0,b=10; Random rand=新的Random(); 公共同步的void add(){ 如果(a >代码> b>代码>中表示两个数,在其他上下文中,变量 a < /> >和 b>代码>引用类A和类B 的实例。将A类字段转换为其他字段,如number1和number2 “假设一个代码块被声明为已同步(x)。进入该代码块的第一个线程获得对象的锁…”对不起,但是代码块之外的代码呢?假设您有一个方法public void f(){val++;synchronized(this){anotherVal++;}}。在这种情况下,如何说“首先进入块的线程获得对象x的锁”?(变量val仍然可以由另一个线程修改,对吗?) import java.util.Random; public class ClassA{ int a = 0, b = 10; Random rand = new Random(); public synchronized void add(){ if (a < 10){ a++; b--; }; } public synchronized void subtract(){ if (b < 10){ b++; a--; } } public synchronized boolean check(){ return a + b == 10; } public static void main(String args[]){ ClassA a = new ClassA(); B ba = new B(a); B bb = new B(a); //notice these two threads are not associated with the object a! Thread t11 = new Thread(bb); Thread t22 = new Thread(ba); t11.start(); t22.start(); } } class B implements Runnable{ ClassA a; B(ClassA a){ this.a = a; } @Override public void run(){ while (a.check()){ if (a.rand.nextInt(2) == 1) a.subtract(); else a.add(); } System.out.print("Out of sync"); } },java,multithreading,Java,Multithreading,我试图更好地理解java多线程。因此,我知道俗话说,只有一个线程可以访问一个对象实例,从而调用该实例的方法(例如,在本例中,类classA中的subtract方法) 但是,当您仍然有相同的classA,a实例,但是与不同的类classB关联的两个线程试图调用a的方法时,会发生什么情况呢?我原以为消息不同步永远不会被打印出来,但它打印了。毕竟,仍然只有一个线程对象实例a,这是否意味着同步在本例中不适用?在您的情况下,将永远不会打印出不同步的,因为在您的情况下,多线程的实现是正确的:执行一系列操作的
classA
中的subtract
方法)
但是,当您仍然有相同的
classA
,a
实例,但是与不同的类classB
关联的两个线程试图调用a
的方法时,会发生什么情况呢?我原以为消息不同步
永远不会被打印出来,但它打印了。毕竟,仍然只有一个线程对象实例a
,这是否意味着同步在本例中不适用?在您的情况下,将永远不会打印出不同步的,因为在您的情况下,多线程的实现是正确的:执行一系列操作的关键方法因此不是原子的,它们的行为就像原子m通过在方法上使用synchronized
关键字执行方法
假设一个代码块被声明为synchronized(x)
。
进入该代码块的第一个线程获得objectx
的锁,并愉快地执行该代码块
任何试图进入同一对象x
上的块的非第一个线程都会通过将该线程放入x
的锁池而被“挂起”。只要当前具有锁的线程离开同步(x)
块,锁池中的随机线程就成为执行该块的下一个线程
在实例方法上使用synchronized
时,它实际上与使用synchronized(this)
包装方法的整个内容相同(对于静态
方法,它将是封闭类的类对象)
因此,在您的例子中,类A
有一个实例,所有同步都发生在它上面
如果要查看不同步
消息,请尝试删除已同步
关键字。过一段时间后,您应该会看到预期的不同步
消息
旁注:
- 因为
不同步
是一条消息,它可能应该打印在System.err
上,而不是System.out
上
- 您可以使用
a.rand.nextBoolean()
,而不是a.rand.nextTint(2)==1
- 如果
class A
的class B
访问字段rand
破坏了封装,您可能希望为class A
提供一个方法randomBoolean()
,该方法返回rand.nextBoolean()
,并从class B
调用该方法randomBoolean()
<> LI>在不同的上下文中具有不同含义的相同变量名可能混淆。在变量<代码> > <代码> >代码> b>代码>中表示两个数,在其他上下文中,变量<代码> a < /> >和<代码> b>代码>引用<代码>类A<代码>和<代码>类B 的实例。将A类
字段转换为其他字段,如number1
和number2
“假设一个代码块被声明为已同步(x)。进入该代码块的第一个线程获得对象的锁…”对不起,但是代码块之外的代码呢?假设您有一个方法
public void f(){val++;synchronized(this){anotherVal++;}}
。在这种情况下,如何说“首先进入块的线程获得对象x的锁”?(变量val
仍然可以由另一个线程修改,对吗?)
import java.util.Random;
public class ClassA{
int a = 0, b = 10;
Random rand = new Random();
public synchronized void add(){
if (a < 10){
a++;
b--;
};
}
public synchronized void subtract(){
if (b < 10){
b++;
a--;
}
}
public synchronized boolean check(){
return a + b == 10;
}
public static void main(String args[]){
ClassA a = new ClassA();
B ba = new B(a);
B bb = new B(a);
//notice these two threads are not associated with the object a!
Thread t11 = new Thread(bb);
Thread t22 = new Thread(ba);
t11.start();
t22.start();
}
}
class B implements Runnable{
ClassA a;
B(ClassA a){
this.a = a;
}
@Override
public void run(){
while (a.check()){
if (a.rand.nextInt(2) == 1)
a.subtract();
else
a.add();
} System.out.print("Out of sync");
}
}