java同步问题
我遇到了 Synchronized 的问题,其行为不符合我的预期,我也尝试使用 volatile 关键字:
共享对象:
public class ThreadValue {
private String caller;
private String value;
public ThreadValue( String caller, String value ) {
this.value = value;
this.caller = caller;
}
public synchronized String getValue() {
return this.caller + " " + this.value;
}
public synchronized void setValue( String caller, String value ) {
this.caller = caller;
this.value = value;
}
}
线程 1:
class CongoThread implements Runnable {
private ThreadValue v;
public CongoThread(ThreadValue v) {
this.v = v;
}
public void run() {
for (int i = 0; i 10; i++) {
v.setValue( "congo", "cool" );
v.getValue();
}
}
}
线程 2:
class LibyaThread implements Runnable {
private ThreadValue v;
public LibyaThread(ThreadValue v) {
this.v = v;
}
public void run() {
for (int i = 0; i 10; i++) {
v.setValue( "libya", "awesome" );
System.out.println("In Libya Thread " + v.getValue() );
}
}
}
调用类:
class TwoThreadsTest {
public static void main (String args[]) {
ThreadValue v = new ThreadValue("", "");
Thread congo = new Thread( new CongoThread( v ) );
Thread libya = new Thread( new LibyaThread( v ) );
libya.start();
congo.start();
}
}
偶尔我会得到“在利比亚线程刚果很酷” 这绝对不应该发生。 我只期望: “利比亚主题利比亚真棒” “在刚果线程刚果很酷”
我不希望它们混合在一起。
I'm having issues with Synchronized not behaving the way i expect, i tried using volatile keyword also:
Shared Object:
public class ThreadValue {
private String caller;
private String value;
public ThreadValue( String caller, String value ) {
this.value = value;
this.caller = caller;
}
public synchronized String getValue() {
return this.caller + " " + this.value;
}
public synchronized void setValue( String caller, String value ) {
this.caller = caller;
this.value = value;
}
}
Thread 1:
class CongoThread implements Runnable {
private ThreadValue v;
public CongoThread(ThreadValue v) {
this.v = v;
}
public void run() {
for (int i = 0; i 10; i++) {
v.setValue( "congo", "cool" );
v.getValue();
}
}
}
Thread 2:
class LibyaThread implements Runnable {
private ThreadValue v;
public LibyaThread(ThreadValue v) {
this.v = v;
}
public void run() {
for (int i = 0; i 10; i++) {
v.setValue( "libya", "awesome" );
System.out.println("In Libya Thread " + v.getValue() );
}
}
}
Calling Class:
class TwoThreadsTest {
public static void main (String args[]) {
ThreadValue v = new ThreadValue("", "");
Thread congo = new Thread( new CongoThread( v ) );
Thread libya = new Thread( new LibyaThread( v ) );
libya.start();
congo.start();
}
}
Occasionally i get "In Libya Thread congo cool"
which should never happen. I expect only:
"In Libya Thread libya awesome"
"In Congo Thread congo cool"
I dont expect them to be mixed.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这些调用可以像下面这样交错:
The calls can interleave like the following:
这应该会给你带来你正在寻找的行为。
线程 1:
线程 2:
This should get you the behavior you're looking for.
Thread 1:
Thread 2:
对 getValue() 和 setValue() 的调用可能会交错。
也就是说,在另一个线程处于 getValue() 或 setValue() 状态的同时,不会有任何线程处于 getValue() 状态,同样,当另一个线程处于 getValue() 或 setValue() 状态时,也不会存在任何线程处于 setValue() 状态。
但是,不能保证单个线程将顺序调用 setValue() getValue() 而不被另一个线程抢占。
基本上,这是完全合法且可能的:
The calls to getValue() and setValue() may be interleaved.
That is, no thread will be in getValue() at the same time another thread is in getValue() or setValue() and likewise no thread will be in setValue() while another thread is in getValue() or setValue().
However, there's no guarantee that a single thread will make sequential calls to setValue() getValue() without being preempted by another thread.
Basically, this is perfectly legal and possible:
它可能是按这个顺序,所以它是正确的:
因此你确实有某种意义上的竞争条件。 同步是每当您尝试调用同步方法时都会获取锁,因此您需要另一种方式来暗示对变量的同步访问。 例如,您可以从方法中删除同步并执行以下操作:
It could be in this order so it's correct:
Therefore you DO have a race conditions in some meaning. Synchronized is acquire a lock whenever you trying to call synchronized method, so you need another way to imply synchronized access to variable. For example you can remove synchronized from methods and do the following: