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

发布于 2024-11-28 14:48:48 字数 2073 浏览 0 评论 0原文

我正在尝试实现一段代码来同步启动Java中的循环服务。这个想法是, // STARTER 注释下的代码应该被视为 Service.go() 方法的一部分,所以如果服务启动失败,我想重新抛出同步异常。仅当我尝试启动线程,等待其执行流程到达某个点,接下来,如果没有问题,我的 go()< /code> 方法退出,线程继续运行,或者,如果出现问题,我可以从 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() 方法中显式运行初始化代码,然后将所有内容传递给线程。

谢谢!

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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

天煞孤星 2024-12-05 14:48:48

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

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();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文