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);
    }
}
4

2 回答 2

5

不,这是不正确的,因为两个线程都可以isbeingwritten == false在将字段更新为true. 既不volatile也不AtomicBoolean解决这个问题。您应该使用适当的同步机制:

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
        }
    }
}
于 2013-05-11T09:53:31.217 回答
0

是的,如果你想让你isbeingwritten一次被一个线程访问,那么你必须使用 volatile 关键字。

volatile 修饰符告诉 JVM 访问该变量的线程必须始终将其自己的变量私有副本与内存中的主副本相协调。

可变变量共享synchronized关键字 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;
    }
}
于 2013-05-11T09:51:57.447 回答