开发者

Synchronizing infinitely looped service's initialization part

I'm trying to implement a piece of code to synchronously start looped service in Java. The idea is, code under // STARTER comment should be considered as piece of Service.go() method, so if service fails to start, I want to re-throw the exception synchronously. That piece of code should only finish in case I've tried to start the thread, waited until its execution flow reached some point and next, if there are no problems, my go() method quits and thread goes on, or, if there were problems, I can re-throw the exception caught in thread's run() method from my go() method. Here's the solution that seems to work fine, but I'm curious if it's possible to make it a couple times shorter :-)

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();
    }
}
}

And also, there's a reason to have initialization code executed within that thread, so, please, don't advise running initialization code explicitly in go() method and then just passing all the stuff to the thread.

Thanks!


How about overriding the Thread.start() method?

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();
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜