2013-05-11 49 views
0

我有一个类boolean变量isbeingwritten。它会跟踪文件是否正在写入。这个类的一个函数调用一些写入文件的线程。这些将首先检查isbeingwritten变量的值,如果它是false,则将其设置为true并开始写入,否则它们将等待。在写作结束时,他们会将值更改回false。如果这个变量是volatile变量应该变得易变吗?

class A 
{ 
    public boolean isbeingwrittenfalse; 
    public void func() 
    { 
     new thread1(); 
     new thread2(); 
    } 
    class thread1 implements Runnable 
    { 
     Thread t; 
     thread1() 
     { 
      t=new Thread (this); 
      t.start(); 
     } 
     public void run() 
     { 
      while(isbeingwritten); 
      isbeingwritten=true; 
      //wrrite very long string 
      isbeingwritten=false; 
     } 
    } 
    class thread2 implements Runnable 
    { 
     Thread t; 
     thread2() 
     { 
      t=new Thread (this); 
      t.start(); 
     } 
     public void run() 
     { 
      while(isbeingwritten); 
      isbeingwritten=true; 
      //wrrite very long string 
      isbeingwritten=false; 
     } 
    } 

下才是正确的解决

public class XSSThread implements Runnable { 
    Thread xt; 

    public void init() { 
     xt = new Thread(this); 
     xt.start(); 
    } 

    public void run() { 
     new Thread1().init(); 
     new Thread2().init(); 
    } 

    public synchronized void saveToFile(String a) { 
     File aFile = new File("filename.txt"); 
     try { 
      BufferedWriter out = new BufferedWriter(new FileWriter(aFile, aFile.exists())); 
      out.write(a + "\r\n"); 
      out.close(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

public class Thread1 extends XSSThread implements Runnable{ 
    Thread xt1; 

    public void init() { 
     xt1 = new Thread(this); 
     xt1.start(); 
    } 

    public void run() { 
     String a;//very long string 
     saveToFile(a); 
    } 
} 

public class Thread2 extends XSSThread implements Runnable { 
    Thread xt2; 

    public void init() { 
     xt2 = new Thread(this); 
     xt2.start(); 
    } 

    public void run() { 
     String a;//very long string 
     saveToFile(a); 
    } 
} 
+0

现在同步正确。但是,您不应该完全改变问题,因为这会让其他人难以将其与答案匹配。请再次更改,以便它包含原始问题和修订问题。 – nosid 2013-05-11 10:09:39

回答

5

不,这是不正确的,因为这两个线程可以看到isbeingwritten == false之前都更新领域truevolatileAtomicBoolean都不能解决此问题。您应该使用适当的同步机制:

private Object writeLock = new Object(); 
class thread1 implements Runnable{ 
    public void run(){ 
     synchronized (writeLock) { 
      //write very long text 
     } 
    } 
} 
class thread2 implements Runnable{ 
    public void run(){ 
     synchronized (writeLock) { 
      //write very long text 
     } 
    } 
} 
+0

当(isbeingwritten)while(isBeingRead == true){try {wait(); \t} catch(InterruptedException e){}} – user2318314 2013-05-11 09:56:15

+0

@ user2318314:'wait'等待另一个线程调用'notify',但在您的示例中没有'notify'。你的意思是不同的? – nosid 2013-05-11 10:00:09

+0

让我编辑并把我正在尝试的确切代码.. – user2318314 2013-05-11 10:02:50

0

是,如果你想使你的isbeingwritten在同一时间,那么你必须使用volatile关键字由一个线程访问。

volatile修饰符告诉JVM访问变量的线程必须始终将自己的变量专用副本与 内存中的主副本进行协调。

易变变量共享​​关键字oj java的可见性功能。这意味着线程会自动查看volatile变量的最新值。

您可以使用它像the.se

public class FileReadingWritingTask extends Thread { 

    private volatile boolean isbeingwritten; 

    public void run() { 
     if (!isbeingwritten) { 
      isbeingwritten = true; 
      // do some stuff... 

      // stuff ends 
      tellMeToStop(); 

     } 
    } 

    public void tellMeToStop() { 
     isbeingwritten = false; 
    } 
}