[英]Java synchronisation and threads
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");
}
}
I'm trying to understand java multi-threading better.我试图更好地理解 java 多线程。 So, I know that the saying goes only one thread can access an object instance and thus call that instance's method (in this case for example, the
subtract
method in class classA
.所以,我知道俗话说只有一个线程可以访问 object 实例,从而调用该实例的方法(在这种情况下,例如 class
classA
中的subtract
方法。
But what happens when, you still have the same instance of classA
, a
but two threads associated with a different class classB
altogether trying to call a
's methods?但是,当您仍然有相同的
classA
实例,但a
两个线程与不同a
class classB
关联时,会发生什么情况? I expected that the message out of sync
would never have been printed, but it did.我希望永远不会打印不
out of sync
的消息,但确实如此。 Afterall, there's still only one object instance a
, does that imply synchronization doesn't apply in this example?毕竟,仍然只有一个 object 实例
a
,这是否意味着同步不适用于此示例?
In your case, out of sync
would never be printed, because for your situation, the multithreading is implemented correctly: The critical methods that perform a sequence of operations and are thus not atomic are made behave like atomic methods by the using the synchronized
keyword on the method.在您的情况下,永远不会打印不
out of sync
,因为对于您的情况,正确实现了多线程:执行一系列操作并因此不是原子的关键方法通过使用synchronized
关键字 on方法。
Assume a code block is declared synchronized (x)
.假设一个代码块被声明为
synchronized (x)
。 The first thread that enters this code block obtains the lock of object x
and happily executes that code block.进入该代码块的第一个线程获得了 object
x
的锁并愉快地执行该代码块。
Any non-first thread that tries to enter the block on the same object x
is "suspended" by putting the thread in the lock pool of x
.任何试图进入同一个 object
x
块的非第一个线程都会通过将线程放入x
的锁池中来“暂停”。 As soon as the thread that currently has the lock leaves the synchronized (x)
block, a random thread from the lock pool becomes the next thread to execute that block.一旦当前拥有锁的线程离开
synchronized (x)
块,锁池中的一个随机线程将成为下一个执行该块的线程。
When using synchronized
on an instance method, it is effectively the same as wrapping the entire content of the method with synchronized (this)
.在实例方法上使用
synchronized
时,它实际上与使用synchronized (this)
包装方法的全部内容相同。 (For static
methods, it would be the class object of the enclosing class.) (对于
static
方法,它将是封闭 ZA2F2ED4F8EBC2CBB16C21A29DC40 的 class object)。
So, in your case, there is one instance of class A
, and all synchronization happens on it.因此,在您的情况下,有一个 class
A
实例,所有同步都发生在它上面。
If you want to see the out of sync
message, try removing the synchronized
keyword.如果您想查看
out of sync
消息,请尝试删除synchronized
关键字。 Then after some time you should see the expected out of sync
message.一段时间后,您应该会看到预期
out of sync
消息。
Sidenotes:旁注:
out of sync
is a message, it should probably be printed on System.err
, not System.out
.out of sync
是一条消息,它可能应该打印在System.err
上,而不是System.out
上。a.rand.nextInt(2) == 1
, you could use a.rand.nextBoolean()
.a.rand.nextBoolean()
而不是a.rand.nextInt(2) == 1
。class B
access field rand
of class A
breaks encapsulation, you might want to give class A
a method randomBoolean()
which does return rand.nextBoolean()
, and call that method randomBoolean()
from class B
. class B
access field rand
of class A
breaks encapsulation, you might want to give class A
a method randomBoolean()
which does return rand.nextBoolean()
, and call that method randomBoolean()
from class B
.class A
, the variables a
and b
denote two numbers, in other contexts, the variables a
and b
refer to instances of class A
and class B
.class A
中,变量a
和b
表示两个数字,在其他上下文中,变量a
和b
指的是class A
和class B
的实例。 Consider renaming the fields of class A
to something else, like number1
and number2
.class A
的字段重命名为其他名称,例如number1
和number2
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.