2013-10-29 32 views
0

我必须做一个程序来模拟一个游戏,其中一个字符串上用'*'表示的猫线程遵循用'。'表示的鼠标线程。这里的同步串类我创建Java - 同步方法无法正常工作

public class SynchronizedString { 

public SynchronizedString(){ 
    Random rand=new Random(); 
    length=rand.nextInt(10)+10; //random integer between 10 and 20 
    theString=new ArrayList<Character>(); 
    for(int i=0; i<length; i++){ 
     theString.add(' '); 
    } 
    mouseIndex=rand.nextInt(length-1); //random initial position for the mouse 
    theString.set(mouseIndex, '.'); 
    catIndex=rand.nextInt(length-1); //random initial position for the cat 
    while(catIndex==mouseIndex){ 
     catIndex=rand.nextInt(length-1); 
    } 
    theString.set(catIndex,'*'); 
} 

public synchronized void set(int position){ 
    String name=Thread.currentThread().getName(); 

    while (occupied==true || occupiedReading==true){ 
     try{ 
      System.err.println(name+" attemped to write"); 
      wait(); //keep on waiting until theString is free to write 
     } catch(InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } //end while 
    occupied=true; 
    if(name.equalsIgnoreCase("CAT")) 
    { 
     theString.set(catIndex,' '); 
     theString.set(position,'*'); 
     catIndex=position; 
    } 
    else if(name.equalsIgnoreCase("MOUSE")) 
    { 
     theString.set(mouseIndex,' '); 
     theString.set(position,'.'); 
     mouseIndex=position; 
    } 

    occupied=false; 
    notifyAll(); 
} 

public synchronized ArrayList<Character> get(){ 
    String name=Thread.currentThread().getName(); 

    while (occupied==true){ 
     try{ 
      System.err.println(name+" attemped to read"); 
      wait(); //keep on waiting until theString is free to write 
     } catch(InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } //end while 
    occupiedReading=true; 

    occupiedReading=false; 
    notifyAll(); 
    return theString; 
} 

public synchronized void print(){ 
    String name=Thread.currentThread().getName(); 
    while(printing) 
     try { 
      System.err.println(name + "attempted to print"); 
      wait(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 

    printing=true; 

    System.out.println(); 
    for(Character c:theString){ 
     System.out.print(c.charValue()); 
    } 
    System.out.println(); 

    printing=false; 
    notify(); 
} 

ArrayList<Character> theString; 
private int length; 
private int mouseIndex; 
boolean printing; 
private int catIndex; 
private boolean occupied=false; 
private boolean occupiedReading=false; 

}

然后,我有两个线程猫和鼠标一直运行后,读取synchronizedString和覆盖它改变自己的立场。

public class Cat extends Thread { 
public Cat(SynchronizedString s){ 
    super("CAT"); 
    sharedString=s; 
    catched=false; 
    position=sharedString.get().indexOf('*'); 
} 

public void run(){ 
    while(catched==false){ 
     if(position==sharedString.get().indexOf('.')); 
      catched=true; 
     toModify=sharedString.get(); 
     position=toModify.indexOf('*'); 
     if(position==(toModify.size()-1)){ 
      direction=false; 
     } 
     if(position==0){ 
      direction=true; 
     } 
     if(direction) 
      position=position+1; 
     else 
      position=position-1; 
     sharedString.set(position); 
    } 
} 

boolean direction=true; 
private ArrayList<Character> toModify; 
boolean catched; 
private int position; 
private SynchronizedString sharedString; 

而且鼠标线

public class Mouse extends Thread { 
public Mouse(SynchronizedString s){ 
    super("MOUSE"); 
    sharedString=s; 
    catched=false; 
    position=sharedString.get().indexOf('.'); 
} 

public void run(){ 
    while(catched==false){ 
     if(position==sharedString.get().indexOf('*')); 
      catched=true; 
     toModify=sharedString.get(); 
     position=toModify.indexOf('.'); 
     if(position==(toModify.size()-1)) 
      position=position-1; 
     else if(position==0) 
      position=position+1; 
     else{ 
      Random rand=new Random(); 
      if(rand.nextBoolean()) 
       position=position+1; 
      else 
       position=position-1; 
     } 
     sharedString.set(position); 
    } 
} 

private ArrayList<Character> toModify; 
private boolean catched; 
private int position; 
private SynchronizedString sharedString; 

下面是我用打印的同步串

public class Display extends Thread { 
public Display(SynchronizedString s){ 
    synchronizedString=s; 
    toPrint=synchronizedString.get(); 
} 

public void run(){ 
    while(toPrint.indexOf('.')!=toPrint.indexOf('*')) 
    { 
     try { 
      sleep(100); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     toPrint=synchronizedString.get(); 
     System.out.println(); 
     for(Character c:toPrint){ 
      System.out.print(c.charValue()); 
     } 
     System.out.println(); 
    } 
} 
ArrayList<Character> toPrint; 
private SynchronizedString synchronizedString; 

显示类,这里的地方,我开始线程:

public class Demo { 
public static void main(String[]args){ 
    SynchronizedString sharedString=new SynchronizedString(); 

    Display display=new Display(sharedString); 
    Cat cat=new Cat(sharedString); 
    Mouse mouse=new Mouse(sharedString); 

    display.start(); 
    cat.start(); 
    mouse.start(); 
} 

问题在于猫和老鼠只移动一次,然后保持在同一个位置。有人可以帮我解决这个问题吗?

+0

你如何开始你的线程工作?你还可以分享那部分代码吗? –

+0

好的,编辑了这个和一个额外的显示线程我用来打印synchronizedString – Andrew

回答

2

你有一个分号你的if语句后:

if(position==sharedString.get().indexOf('*')); 
      catched=true; 

在两个线程。所以catched = true被立即设置,并且线程停止工作。