静态varibale无法从线程更改

时间:2016-06-13 10:09:51

标签: java multithreading

在下面的代码中,我创建了类FMSHandler来处理从main方法传递给它的字符串值,如下所示

while (true) {
        fmsHandler.process("param1_" + (++cnt) + ", param2_" + (cnt));
    }

我想要做的是,允许每3秒执行一次处理。或者换句话说,每3秒我读取从主要传递的消息到前面提到的代码并执行 进一步处理。为此,我创建了一个名为sIsProcessing的静态布尔变量来调节处理。这个静态变量最初是假的,只要有 正在处理的消息将成立,当执行处理的线程如下面的代码所示时,它将被设置回false。

我面临的问题是,尽管while循环运行永远,但处理应用一次,并且不会像我预期的那样每3秒重复一次。

请告知代码,让我知道错误在哪里

主要

public class Main {

private final static String TAG = Main.class.getSimpleName(); 

public static void main(String[] args) {
    FMSHandler fmsHandler = new FMSHandler();
    long startTime = TimeUtils.getTSSec();
    int cnt = 0;

    while (true) {
        fmsHandler.process("param1_" + (++cnt) + ", param2_" + (cnt));
    }
}

}

FMSHandler

public class FMSHandler {
private final static String TAG = FMSHandler.class.getSimpleName();
private static boolean sIsProcessing = false;
private static int sCnt = 0;

public void process(String fmsMsg) {

    if (!sIsProcessing) {
        sIsProcessing = true;
        Log.w(TAG, "FMSHandler", "new task to be processed");
        new HandlerThread(HandlerThread.class.getSimpleName() + "_" + (FMSHandler.sCnt++), fmsMsg).start();
    }

}

class HandlerThread extends Thread {
    private String[] mSplittedFMS = null;
    private String mThreadName = "";

    public HandlerThread(String threadName, String fmsMsg) {
        // TODO Auto-generated constructor stub
        this.setName(threadName);
        this.mSplittedFMS = this.toArray(fmsMsg);
    }

    private String[] toArray(String fmsMsg) {
        // TODO Auto-generated method stub
        return fmsMsg.split(",");
    }

    public void run() {
        Log.w(TAG, "HandlerThread.run()", this.getName() + " started");

        for (int i = 0; i < this.mSplittedFMS.length; i++) {
            Log.i(TAG, "HandlerThread.run()", "this.mSplittedFMS: " + this.mSplittedFMS[i]);
        }

        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        Log.w(TAG, "HandlerThread.run()", this.getName() + " finished");
        sIsProcessing = false;
    }
}

}

1 个答案:

答案 0 :(得分:1)

您应该将sIsProcessing变量声明为volatile或使用AtomicBoolean

此外,目前,很多传递给process(...)的邮件都会被跳过,我不确定这是不是你的意图。

如果要阻止跳过消息,则需要使用同步在处理消息时阻止主线程的循环。

我的建议是完全重写此内容并使用Timer以及concurrency包中的某种队列,例如ArrayBlockingQueue

以下是一个例子:

public static final ArrayBlockingQueue<String> messages = new ArrayBlockingQueue<>(100);
public static final AtomicBoolean keepRunning = new AtomicBoolean(true);
.....
new Thread(new Runnable(){
    public void run(){
        while(keepRunning.get()){
            String message = messages.take();// blocks until a message is avaiable
            synchronized(Thread.currentThread()){
                Thread.currentThread().wait(3000);// pause 3 seconds before starting to process the next message.
            }
        }
    }
}).start();

// add messages from some other class;
MessagesProcessor.messages.add("some message");