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はい、一度に 1 つのスレッドからアクセスできるようにしたい場合は、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 に答える