在java中,线程本地缓存的内存在被销毁时被刷新到主内存中???

时间:2016-07-04 06:37:01

标签: java android multithreading

我正在尝试设计一个使用Executors.newSingleThreadExecutor()

制作的工作线程的Android应用程序

但是我只希望该工作线程处理主线程发送的连续任务,同时保存属于该工作线程的一些信息。 (主线程不需要知道,只有工作线程应该在内部保留该信息。

// State saver class , once made by main thread only accessed by worker thread

public class StateSaver{

    public int count;

}

// Runnable obj that will be sent to worker thread from main thread
public class rnbl implements Runnable{

    final public StateSaver sv;

    public rnbl(StateSaver sv){
        this.sv = sv;
    }

    @Override
    public void run(){
        sv.count++;
    }
}

// Main Thread

ExecutorService ex = Executors.newSingleThreadExecutor();

StateSaver sv = new StateSaver();

public void functionCalledByMainThread(){



    ex.submit(new rnbl(sv));

}

然而问题是我发现当newSingleThreadExecutor长时间处于空闲状态时,它可能只是破坏它所做的线程并在需要时用新的线程替换它。

所以我担心的是,如果出现以下情况怎么办? :

  1. 工作线程更新了状态变量

  2. 变量在线程缓存内存中更新但尚未应用于主内存(变量不应该是易失性的)

  3. 工作线程被破坏

  4. 更新永远不会应用于主内存......

  5. 然后,如果执行程序创建一个新线程继续执行该任务,那么保存的状态可能不正确吗?当然使用volatile应该很容易,但我不需要使用volatile

    或者是否可以保证当一个线程被销毁时,对变量所做的所有更改都会被刷新到主内存中?

2 个答案:

答案 0 :(得分:1)

如果要确保当后终止的线程所做的更改对另一个线程可见,则可以使用Thread.join()。这样可以保证发生在之前的关系。

例如:

 Thread t = new Thread(new SomeRunnable());
 t.start();
 // do stuff
 t.join();
 // After the 'join', all memory writes made by Thread t are 
 // guaranteed to be visible to the current thread.

但实际上你问的是ExecutorService线程无法用于“加入”。

以下内存一致性保证适用于ExecutorService

  

在向Runnable 提交CallableExecutorService任务之前,线程中的操作发生在该任务采取的任何操作之前,反过来发生 - 之前通过Future.get()检索结果。

因此,获得所需一致性的方法是在get()上为任务调用Future

答案 1 :(得分:1)

ExecutorService只能在' run()'之后删除线程。方法完成了。只需实现线程生命周期的自定义协议(等待和处理消息中的实时forewer或者为特殊消息刷新状态和死亡):

class App {
    static final String KILLER_MSG = "KILLER";
    public static void main(String[] args) {
        BlockingQueue<String> tasks = new ArrayBlockingQueue<String>(256);
        ExecutorService pool = Executors.newCachedThreadPool();

        // master / task producer
        pool.submit(() -> {
            tasks.add("task-0");
            tasks.add("task-1");
            tasks.add("task-2");
            tasks.add(KILLER_MSG);
        });

        // slave / task consumer / worker
        pool.submit(() -> {
            while (true) {
                String task = tasks.take();
                if (KILLER_MSG.equals(task)) {
                    // flush state here
                    break; // and die
                } else {
                    // process 'task' here
                    System.out.println("TASK: " + task);
                }
            }
        });
    }
}