我正在构建一个程序,该程序需要构造一些需要如此大量计算才能创建的对象,我最聪明的过程是将它们构建在自己的专用线程中,而主线程会不断地研究其他事物,直到这些对象成为对象为止。需要。

因此,我考虑创建一个专门设计用于在其自己的线程中创建自定义对象的特殊类。像这样:

public abstract class DedicatedThreadBuilder<T> {

    private T object;

    public DedicatedThreadBuilder() {
        DedicatedThread dt = new DedicatedThread(this);
        dt.start();
    }

    private void setObject(T i) {
        object = i;
    }

    protected abstract T constructObject();

    public synchronized T getObject() {
        return object;
    }

    private class DedicatedThread extends Thread {

        private DedicatedThreadBuilder dtb;

        public DedicatedThread(DedicatedThreadBuilder builder){
            dtb = builder;
        }

        public void run() {
            synchronized(dtb) {
                dtb.setObject(dtb.constructObject());
            }
        }

    }

}


我唯一关心的是,只有在主线程(即构造DedicatedThreadBuilder的线程)在DedicatedThreadBuilder上具有同步锁的情况下,该机制才能正常工作,直到构造完成,从而阻止DedicatedThread尝试构建产品对象,直到它完成为止。已完成DedicatedThreadBuilder的构建。为什么?因为毫无疑问,将需要用参数构造DedicatedThreadBuilder的子类,所以需要将其传递到它们自己的私有存储中,以便可以在constructObject()过程中使用它们。

例如

public class JellybeanStatisticBuilder extends DedicatedThreadBuilder<JellybeanStatistics> {

    private int greens;
    private int blacks;
    private int yellows;

    public JellybeanStatisticBuilder(int g, int b, int y) {
        super();
        greens = g;
        blacks = b;
        yellows = y;
    }

    protected JellybeanStatistics constructObject() {
        return new JellybeanStatistics(greens, blacks, yellows);
    }

}


只有在对象被完全构造之后才将其阻塞到其他线程,这才可以正常工作。否则,DedicatedThread可能会在分配必要的变量之前尝试构建对象。

那是Java的工作方式吗?

最佳答案

我认为您想要的是具有某种同步的工厂类:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;

public class SyncFactory<T> {
    // alternatively, use newCachedThreadPool or newFixedThreadPool if you want to allow some degree of parallel construction
    private ExecutorService executor = Executors.newSingleThreadExecutor();

    public Future<T> create() {
        return executor.submit(() -> {
            return new T();
        });
    }
}


现在,您可以用T替换可能需要在T就绪之前使用的Future<T>用法,并可以选择调用其Future.get()方法以阻塞直到准备就绪,设置超时或调用Future.isDone()检查结构是否畅通无阻。另外,您可能不希望轮询Future,而是希望工厂调用回调或发布事件以在完成构造后通知主线程。

09-30 22:49
查看更多