变量应该变化吗?

时间:2013-05-11 09:48:59

标签: java multithreading

我有一个类,其中有一个名为boolean的{​​{1}}变量。它会跟踪文件是否正在写入。该类的函数调用一些写入文件的线程。这些将首先检查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;
        }
    }

2 个答案:

答案 0 :(得分: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
        }
    }
}

答案 1 :(得分: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;
    }
}