我有一个类,其中有一个名为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;
}
}
答案 0 :(得分: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
}
}
}
答案 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;
}
}