diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/launcher/Launcher.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/launcher/Launcher.java deleted file mode 100644 index 1a88a2db..00000000 --- a/neutrino-core/src/main/java/fun/asgc/neutrino/core/launcher/Launcher.java +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Copyright (c) 2022 aoshiguchen - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package fun.asgc.neutrino.core.launcher; - -/** - * - * @author: aoshiguchen - * @date: 2022/6/16 - */ -public interface Launcher { - - /** - * 启动 - */ - void launch(); - -} diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/launcher/NeutrinoLauncher.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/launcher/NeutrinoLauncher.java index d556b30a..62b84a5f 100644 --- a/neutrino-core/src/main/java/fun/asgc/neutrino/core/launcher/NeutrinoLauncher.java +++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/launcher/NeutrinoLauncher.java @@ -40,58 +40,38 @@ import java.lang.management.ManagementFactory; * @date: 2022/6/16 */ @Slf4j -public class NeutrinoLauncher implements Launcher { +public class NeutrinoLauncher { private Environment environment; private ApplicationContainer applicationContainer; - private static volatile boolean running = true; - private static Object lock = new Object(); - public static void run(final Class> clazz, final String[] args) { + public static SystemUtil.RunContext run(final Class> clazz, final String[] args) { Assert.notNull(clazz, "启动类不能为空!"); - - ThreadUtil.run(() -> { - new NeutrinoLauncher(clazz, args).launch(); - }); + return new NeutrinoLauncher(clazz, args).launch(); } public static void runSync(final Class> clazz, final String[] args) { - run(clazz, args); - - synchronized (lock) { - while (running) { - try { - lock.wait(); - } catch (Exception e) { - // ignore - } - } - } + run(clazz, args).sync(); log.info("Application already stop."); } - public NeutrinoLauncher(Class> clazz, String[] args) { + private NeutrinoLauncher(Class> clazz, String[] args) { this.environment = new Environment() .setMainClass(clazz) .setMainArgs(args); } - @Override - public void launch() { + private SystemUtil.RunContext launch() { StopWatch stopWatch = new StopWatch(); stopWatch.start(); environmentInit(); this.applicationContainer = new DefaultApplicationContainer(environment); - SystemUtil.addShutdownHook(() -> { - synchronized (lock) { - this.applicationContainer.destroy(); - running = false; - lock.notify(); - } - }); + SystemUtil.RunContext runContext = SystemUtil.waitProcessDestroy(() -> this.applicationContainer.destroy()); stopWatch.stop(); printLog(environment, stopWatch); + + return runContext; } /** diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/util/SystemUtil.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/util/SystemUtil.java index cf8b17fe..9922008d 100644 --- a/neutrino-core/src/main/java/fun/asgc/neutrino/core/util/SystemUtil.java +++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/util/SystemUtil.java @@ -22,6 +22,8 @@ package fun.asgc.neutrino.core.util; +import fun.asgc.neutrino.core.base.CodeBlock; + /** * * @author: aoshiguchen @@ -33,4 +35,52 @@ public class SystemUtil { Runtime.getRuntime().addShutdownHook(new Thread(runnable)); } + /** + * 等待进程销毁 + * @return + */ + public static RunContext waitProcessDestroy() { + return waitProcessDestroy(null); + } + + /** + * 等待进程销毁 + * @param destroy + * @return + */ + public static RunContext waitProcessDestroy(CodeBlock destroy) { + RunContext context = new RunContext(); + SystemUtil.addShutdownHook(() -> { + synchronized (context) { + if (null != destroy) { + destroy.execute(); + } + context.stop(); + context.notify(); + } + }); + return context; + } + + + public static class RunContext { + private volatile boolean running = true; + + public void sync() { + synchronized (this) { + while (running) { + try { + this.wait(); + } catch (Exception e) { + // ignore + } + } + } + } + + private void stop() { + this.running = false; + } + + } } diff --git a/neutrino-core/src/test/java/fun/asgc/neutrino/core/util/LockUtilTest.java b/neutrino-core/src/test/java/fun/asgc/neutrino/core/util/LockUtilTest.java new file mode 100644 index 00000000..141a2f25 --- /dev/null +++ b/neutrino-core/src/test/java/fun/asgc/neutrino/core/util/LockUtilTest.java @@ -0,0 +1,63 @@ +/** + * Copyright (C) 2018-2022 Zeyi information technology (Shanghai) Co., Ltd. + *
+ * All right reserved. + *
+ * This software is the confidential and proprietary + * information of Zeyi Company of China. + * ("Confidential Information"). You shall not disclose + * such Confidential Information and shall use it only + * in accordance with the terms of the contract agreement + * you entered into with Zeyi inc. + */ +package fun.asgc.neutrino.core.util; + +import lombok.Data; +import org.checkerframework.checker.units.qual.A; +import org.junit.Test; + +/** + * + * @author: wen.y + * @date: 2022/6/20 + */ +public class LockUtilTest { + private static volatile A a; + + /** + * 没有双重校验锁,并发执行容易产生多个实例 + */ + @Test + public void test1() { + for (int i = 0; i < 10; i++) { + ThreadUtil.run(() -> { + if (a == null) { + a = new A(); + } + }); + } + SystemUtil.waitProcessDestroy().sync(); + } + + /** + * 使用双重校验锁,并发执行,只产生一个实例 + */ + @Test + public void test2() { + for (int i = 0; i < 10; i++) { + ThreadUtil.run(() -> { + LockUtil.doubleCheckProcess(() -> a == null, + LockUtilTest.class, + () -> a = new A()); + }); + } + SystemUtil.waitProcessDestroy().sync(); + } + + @Data + public static class A { + public A() { + System.out.println("new instance."); + } + } +} diff --git a/neutrino-core/src/test/java/fun/asgc/neutrino/core/util/SystemUtilTest.java b/neutrino-core/src/test/java/fun/asgc/neutrino/core/util/SystemUtilTest.java new file mode 100644 index 00000000..211c42a6 --- /dev/null +++ b/neutrino-core/src/test/java/fun/asgc/neutrino/core/util/SystemUtilTest.java @@ -0,0 +1,40 @@ +/** + * Copyright (C) 2018-2022 Zeyi information technology (Shanghai) Co., Ltd. + *
+ * All right reserved. + *
+ * This software is the confidential and proprietary + * information of Zeyi Company of China. + * ("Confidential Information"). You shall not disclose + * such Confidential Information and shall use it only + * in accordance with the terms of the contract agreement + * you entered into with Zeyi inc. + */ +package fun.asgc.neutrino.core.util; + +import org.junit.Test; + +/** + * + * @author: wen.y + * @date: 2022/6/20 + */ +public class SystemUtilTest { + + @Test + public void run() { + ThreadUtil.run(() -> { + for (int i = 0; i < 10; i ++) { + try { + System.out.println(i); + Thread.sleep(1000); + } catch (Exception e) { + + } + } + }); + + SystemUtil.waitProcessDestroy(() -> System.out.println("进程销毁")).sync(); + } + +} diff --git a/neutrino-proxy-client/src/main/java/fun/asgc/neutrino/proxy/client/ProxyClient.java b/neutrino-proxy-client/src/main/java/fun/asgc/neutrino/proxy/client/ProxyClient.java index 63236034..7de569f3 100644 --- a/neutrino-proxy-client/src/main/java/fun/asgc/neutrino/proxy/client/ProxyClient.java +++ b/neutrino-proxy-client/src/main/java/fun/asgc/neutrino/proxy/client/ProxyClient.java @@ -34,7 +34,7 @@ import fun.asgc.neutrino.core.launcher.NeutrinoLauncher; public class ProxyClient { public static void main(String[] args) { - NeutrinoLauncher.runSync(ProxyClient.class, args); + NeutrinoLauncher.run(ProxyClient.class, args); } } diff --git a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/ProxyServer.java b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/ProxyServer.java index 64549a2f..fa1c16f8 100644 --- a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/ProxyServer.java +++ b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/ProxyServer.java @@ -34,7 +34,7 @@ import fun.asgc.neutrino.core.launcher.NeutrinoLauncher; public class ProxyServer { public static void main(String[] args) { - NeutrinoLauncher.runSync(ProxyServer.class, args); + NeutrinoLauncher.run(ProxyServer.class, args); } }