同步无限循环服务的初始化部分

时间:2011-08-09 19:11:30

标签: java concurrency synchronization

我正在尝试实现一段代码来同步启动Java中的循环服务。我的想法是,// STARTER注释下的代码应被视为Service.go()方法的一部分,因此如果服务无法启动,我想同步重新抛出异常。这条代码应该只在我尝试启动线程的情况下完成,等待直到它的执行流程达到某个点,然后,如果没有问题,我的go()方法退出和线程继续,或者,如果有问题,我可以从我的go()方法重新抛出线程的run()方法中捕获的异常。这里的解决方案似乎运行良好,但我很好奇是否有可能缩短几倍: - )

public class Program {

private static boolean started;
private static Throwable throwable;

public static void main(String[] args) {
    final Object startedSetterLock = new Object();

    Thread thread = new Thread() {
        public void run() {
            System.out.printf("trying to start...\n");

            boolean ok;
            Throwable t = null;
            try {
                init();
                ok = true;
            } catch(Exception e) {
                ok = false;
                t = e;
            }

            synchronized(startedSetterLock) {
                started = ok;
                throwable = t;
                startedSetterLock.notifyAll();
            }

            if(!ok) {
                return;
            }

            while(true) {
                try {
                    System.out.printf("working...\n");
                    Thread.sleep(1000);
                } catch(InterruptedException e) {
                    System.out.printf("interrupted\n");
                }                   
            }
        }

        private void init() throws Exception { throw new Exception(); } // may throw
    };

            // STARTER
    synchronized(startedSetterLock) {
        thread.start();
        try {           
            startedSetterLock.wait();
        } catch(InterruptedException e) {
            System.out.printf("interrupted\n");
        }
    }       

    // here I'm 100% sure that service has either started or failed to start
    System.out.printf("service started: %b\n", started);
    if(!started) {
        throwable.printStackTrace();
    }
}
}

而且,有一个原因在该线程中执行初始化代码,因此,请不要建议在go()方法中明确地运行初始化代码,然后只传递所有东西到线程。

谢谢!

1 个答案:

答案 0 :(得分:2)

覆盖Thread.start()方法怎么样?

public static void main(String[] args) {
    Thread t = new Thread() {
        public void run() {
            while (true) {
                try {
                    System.out.printf("working...\n");
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    System.out.printf("interrupted\n");
                }
            }
        }

        @Override
        public synchronized void start() {
            try {
                init();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            super.start();
        }

        private void init() throws Exception {
            throw new Exception("test");
        }
    };

    t.start();
}