2009-07-16 160 views
-2

我在与同步行为不我所期望的方式问题,我尝试使用volatile关键字也:的Java同步和线程

共享对象

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 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", "lame"); 
      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(); 
    } 
} 

偶尔我得到"In Libya Thread congo cool" 这绝不应该发生。我只希望:
"In Libya Thread libya awesome"
"In Congo Thread congo cool"

我不希望他们进行混合。

+1

你怎么能期待“在利比亚螺纹利比亚真棒”?你的程序不包含“真棒” – 2009-07-16 05:30:25

回答

1

会发生什么事是以下为:

  1. 线程1设定值
  2. 线程2套价值
  3. 线程1读取由线程2

设置为了解决这个问题,你需要的价值有守卫GET 1个锁定对象/设置函数调用这两个线程。做到这一点的最好方法是创建一个同时执行set和get的额外同步方法。但有时候这是不可取的。在这种情况下,给两个线程一个锁对象。这只是一个普通的对象。然后它们在一个同步块中使用。

每个线程的实现都像下面这样,注意它们需要有完全相同的对象!

Object lockObject = new Object(); 
Thread t1 = new CongroThread(v, lockObject); 
Thread t2 = new LibyaThread(v, lockObject); 

... 

class CongoThread implements Runnable { 
    private ThreadValue v; 
    private Object lockObject; 

    public CongoThread(ThreadValue v, Object lockObject) { 
    this.v = v; 
    this.lockObject = lockObject, 
    } 
    public void run() { 
     for (int i = 0; i < 10; i++) { 
      synchronized(lockObject) 
      { 
       v.setValue("congo", "lame"); 
       v.getValue(); 
      } 
     } 
    } 
} 
0

您是否同步System.out.print调用?没有同步,它们是线程安全的,但不能以正确的顺序发射。

synchronzied(System.out) { 
    System.out.print(....); 
    System.out.flush(); 
} 
1

你只是同步访问getValuesetValue分别是这两个内胆

v.setValue("congo", ..); 
v.getValue(); 

当然然后两个线程可以交错之间一个的setValuegetValue