【问题标题】:Variable visible in whole application but not static变量在整个应用程序中可见但不是静态的
【发布时间】:2017-04-16 15:38:11
【问题描述】:

在我的应用程序中,我有两个类,它们实现了两种不同的文件处理方法。

现在我需要添加一个名为 isProcessing 的布尔变量,每次这两个类中的一个开始处理文件时,该变量都会设置为 true。处理完成后,它应该返回 false。

每当 X 类试图处理一个文件时,它应该检查 Y 类此时是否正在处理。

如何在不声明顶级静态全局变量的情况下实现这一点?

【问题讨论】:

  • 您考虑过使用共享文件系统锁吗? stackoverflow.com/questions/128038/…
  • 您可能想要使用单例模式。
  • 考虑到静态正是您要寻找的东西,您能解释一下为什么不想使用它吗?
  • 我已经在下面的答案中写了它,但我会重复这次谈话。我认为静态变量被认为是一种可怕的反模式。

标签: java


【解决方案1】:

有很多方法...但是为什么不使用static 呢?


您可以拥有一个带有全局变量isProcessing 的公共类,它有两个嵌套类XY,因此两者都可以看到变量。虽然如果您正在使用多个线程,那么您还需要同步变量....

public class Connector{

private volatile boolean isProcessing; //i am using volatile in case you have Threads but you need to further improve it.


  protected class X{

      public X(){ ... }

  }


  protected class Y{

   public Y(){....}

  }

}

更多链接:

Java share a variable between two threads

http://java-tweets.blogspot.gr/2012/01/difference-between-volatile-and.html

http://javarevisited.blogspot.gr/2011/04/synchronization-in-java-synchronized.html


强烈建议您也从这里阅读答案:

What is the use of a private static variable in Java?

【讨论】:

  • 我认为静态变量是一种糟糕的反模式。
  • @Bobzone 有时非常有用。想象一下,如果你想在很多类之间共享一个变量......虽然对于每件事都有多种方法来实现它......
【解决方案2】:

互斥

一种方法是使用锁定对象,mutex,在您的处理类之间共享。

public static void main(String[] args) {

    ProcessingMutex mutex = new ProcessingMutex();

    Processor fileProcessorOne = new ProcessorOne(mutex);
    Processor fileProcessorTwo = new ProcessorTwo(mutex);

    // start threads and do your stuff

}

互斥对象将包含一些逻辑来防止一个线程覆盖其他线程的锁:

public class ProcessingMutex {

    private Object processor = null;

    public boolean processing() {
        return processor != null;
    }

    public synchronized void start(Object p) {
        if (processor == null) {
            processor = p;
        } else {
            throw new IllegalStateException("Already processing!");
        }
    }

    public synchronized void finished(Object p) {
        if (processor == p) {
            processor = null;
        } else {
            // Optional: throw new IllegalStateException("Cannot reset other processors flag!");
        }
    }

}

由于它们共享锁定机制,我从实现锁定的同一个父级派生了两个处理器类:

public abstract class Processor /* extends Runnable? */ {
    private final ProcessingMutex mutex;

    public Processor(ProcessingMutex mutex) {
        this.mutex = mutex;
    }

    public void processFile() {
        if (getLock()) {
            try {
                doProcess();
            } finally {
                // make sure to release lock -> finally
                releaseLock();
            }
        }
    }

    protected abstract void doProcess();

    private boolean getLock() {
        // query and set mutex in synchronized block to prevent interference with other thread
        synchronized (mutex) {
            if (!mutex.processing()) {
                mutex.start(this);
            }
        }
        return false;
    }

    private void releaseLock() {
        mutex.finished(this);
    }

}

public class ProcessorOne extends Processor {

    public ProcessorOne(ProcessingMutex mutex) {
        super(mutex);
    }

    @Override
    protected void doProcess() {
        // TODO add file processing algorithm one
    }

}

public class ProcessorTwo extends Processor {

    public ProcessorTwo(ProcessingMutex mutex) {
        super(mutex);
    }

    @Override
    protected void doProcess() {
        // TODO add file processing algorithm two
    }

}

免责声明: 请注意,这只是一个非常基本的(深夜)版本来展示我的想法。根据您的应用程序的需要,它必须在线程安全方面得到加强。

编辑:

java.util.concurrent

您当然可以使用 Java 提供的 Lock 对象之一(请参阅java.util.concurrent API doc),正如其他答案中所建议的那样:https://stackoverflow.com/a/3493788/4791599

【讨论】:

    猜你喜欢
    • 2012-06-13
    • 2014-04-23
    • 2021-05-09
    • 2012-04-23
    • 1970-01-01
    • 2012-11-24
    • 1970-01-01
    • 2013-03-15
    • 1970-01-01
    相关资源
    最近更新 更多