From c065f693a9b738d7099e34c141f5d82af65b9e52 Mon Sep 17 00:00:00 2001 From: redkale Date: Thu, 26 Oct 2023 15:18:59 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0AnonymousThreadFactory?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/redkale/annotation/Scheduled.java | 5 +- .../redkale/cluster/CacheClusterAgent.java | 7 +- src/main/java/org/redkale/net/sncp/Sncp.java | 10 ++- .../org/redkale/source/CacheMemorySource.java | 6 +- .../redkale/util/AnonymousThreadFactory.java | 39 +++++++++++ src/main/java/org/redkale/util/Utility.java | 66 +++++++++++++++++++ 6 files changed, 117 insertions(+), 16 deletions(-) create mode 100644 src/main/java/org/redkale/util/AnonymousThreadFactory.java diff --git a/src/main/java/org/redkale/annotation/Scheduled.java b/src/main/java/org/redkale/annotation/Scheduled.java index 03ed8ebbd..42b7e6b80 100644 --- a/src/main/java/org/redkale/annotation/Scheduled.java +++ b/src/main/java/org/redkale/annotation/Scheduled.java @@ -7,7 +7,8 @@ import java.lang.annotation.*; import java.util.concurrent.TimeUnit; /** - * 定时任务标记,只能作用于Service的方法上, 功能类似Spring里的Scheduled注解 + * 定时任务标记,只能作用于Service的protected且无参数方法上, 功能类似Spring里的Scheduled注解 + * * *

* 详情见: https://redkale.org @@ -30,5 +31,5 @@ public @interface Scheduled { String initialDelay() default "-1"; TimeUnit timeUnit() default TimeUnit.MILLISECONDS; - + } diff --git a/src/main/java/org/redkale/cluster/CacheClusterAgent.java b/src/main/java/org/redkale/cluster/CacheClusterAgent.java index 47fa96776..a88049e39 100644 --- a/src/main/java/org/redkale/cluster/CacheClusterAgent.java +++ b/src/main/java/org/redkale/cluster/CacheClusterAgent.java @@ -116,12 +116,7 @@ public class CacheClusterAgent extends ClusterAgent implements Resourcable { @Override public void start() { if (this.scheduler == null) { - AtomicInteger counter = new AtomicInteger(); - this.scheduler = new ScheduledThreadPoolExecutor(1, (Runnable r) -> { - final Thread t = new Thread(r, "Redkale-" + CacheClusterAgent.class.getSimpleName() + "-Check-Thread-" + counter.incrementAndGet()); - t.setDaemon(true); - return t; - }); + this.scheduler = Utility.newScheduledExecutor(1, "Redkale-" + CacheClusterAgent.class.getSimpleName() + "-Check-Thread-%s"); } if (this.taskFuture != null) { this.taskFuture.cancel(true); diff --git a/src/main/java/org/redkale/net/sncp/Sncp.java b/src/main/java/org/redkale/net/sncp/Sncp.java index c083f9fa2..b937bbba8 100644 --- a/src/main/java/org/redkale/net/sncp/Sncp.java +++ b/src/main/java/org/redkale/net/sncp/Sncp.java @@ -80,6 +80,13 @@ public abstract class Sncp { if (method.isSynthetic()) { continue; } + if (method.getAnnotation(Scheduled.class) != null) { + if (Modifier.isStatic(method.getModifiers()) + || !Modifier.isProtected(method.getModifiers()) || method.getParameterCount() > 0) { + throw new SncpException(Scheduled.class.getSimpleName() + " must be on protected and non-parameter method, but on " + method); + } + continue; + } if (Modifier.isStatic(method.getModifiers())) { continue; } @@ -92,9 +99,6 @@ public abstract class Sncp { if (method.getAnnotation(ResourceListener.class) != null) { continue; } - if (method.getAnnotation(Scheduled.class) != null) { - continue; - } if (method.getName().equals("getClass") || method.getName().equals("toString")) { continue; } diff --git a/src/main/java/org/redkale/source/CacheMemorySource.java b/src/main/java/org/redkale/source/CacheMemorySource.java index 82b6fc227..dfca6031e 100644 --- a/src/main/java/org/redkale/source/CacheMemorySource.java +++ b/src/main/java/org/redkale/source/CacheMemorySource.java @@ -144,11 +144,7 @@ public final class CacheMemorySource extends AbstractCacheSource { } } if (scheduler == null) { - this.scheduler = new ScheduledThreadPoolExecutor(1, (Runnable r) -> { - final Thread t = new Thread(r, "Redkale-" + self.getClass().getSimpleName() + "-" + resourceName() + "-Expirer-Thread"); - t.setDaemon(true); - return t; - }); + this.scheduler = Utility.newScheduledExecutor(1, "Redkale-" + CacheMemorySource.class.getSimpleName() + "-" + resourceName() + "-Expirer-Thread"); final List keys = new ArrayList<>(); scheduler.scheduleWithFixedDelay(() -> { try { diff --git a/src/main/java/org/redkale/util/AnonymousThreadFactory.java b/src/main/java/org/redkale/util/AnonymousThreadFactory.java new file mode 100644 index 000000000..cb129bbc3 --- /dev/null +++ b/src/main/java/org/redkale/util/AnonymousThreadFactory.java @@ -0,0 +1,39 @@ +///* +// * +// */ +//package org.redkale.util; +// +//import java.util.concurrent.ThreadFactory; +//import java.util.function.Function; +// +///** +// * 虚拟线程工厂 +// * +// * @author zhangjx +// * @since 2.8.0 +// */ +//public class AnonymousThreadFactory implements ThreadFactory, Function { +// +// private final ThreadFactory factory = Thread.ofVirtual().factory(); +// +// private final String name; +// +// public AnonymousThreadFactory(String name) { +// this.name = name; +// } +// +// @Override +// public ThreadFactory apply(String name) { +// return new AnonymousThreadFactory(name); +// } +// +// @Override +// public Thread newThread(Runnable r) { +// Thread t = factory.newThread(r); +// if (name != null) { +// t.setName(name); +// } +// return t; +// } +// +//} diff --git a/src/main/java/org/redkale/util/Utility.java b/src/main/java/org/redkale/util/Utility.java index a09e056c7..e664170f5 100644 --- a/src/main/java/org/redkale/util/Utility.java +++ b/src/main/java/org/redkale/util/Utility.java @@ -18,6 +18,7 @@ import java.security.*; import java.time.*; import java.util.*; import java.util.concurrent.*; +import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.ReentrantLock; import java.util.function.*; import java.util.stream.Stream; @@ -83,6 +84,11 @@ public final class Utility { private static final Function virtualThreadLocalFunction; + //org.redkale.util.AnonymousThreadFactory + private static final String functionThreadFactoryBinary = "cafebabe0000004100450a000200030700040c000500060100106a6176612f6c616e672f4f626a6563740100063c696e69743e0100032829560a0008000907000a0c000b000c0100106a6176612f6c616e672f5468726561640100096f665669727475616c01002628294c6a6176612f6c616e672f546872656164244275696c646572244f665669727475616c3b0b000e000f0700100c001100120100226a6176612f6c616e672f546872656164244275696c646572244f665669727475616c010007666163746f727901002628294c6a6176612f7574696c2f636f6e63757272656e742f546872656164466163746f72793b09001400150700160c001100170100276f72672f7265646b616c652f7574696c2f416e6f6e796d6f7573546872656164466163746f72790100244c6a6176612f7574696c2f636f6e63757272656e742f546872656164466163746f72793b09001400190c001a001b0100046e616d650100124c6a6176612f6c616e672f537472696e673b0a0014001d0c0005001e010015284c6a6176612f6c616e672f537472696e673b29560b002000210700220c002300240100226a6176612f7574696c2f636f6e63757272656e742f546872656164466163746f72790100096e6577546872656164010028284c6a6176612f6c616e672f52756e6e61626c653b294c6a6176612f6c616e672f5468726561643b0a000800260c0027001e0100077365744e616d650700290100106a6176612f6c616e672f537472696e670a0014002b0c002c002d0100056170706c79010038284c6a6176612f6c616e672f537472696e673b294c6a6176612f7574696c2f636f6e63757272656e742f546872656164466163746f72793b07002f01001b6a6176612f7574696c2f66756e6374696f6e2f46756e6374696f6e010004436f646501000f4c696e654e756d6265725461626c650100124c6f63616c5661726961626c655461626c65010004746869730100294c6f72672f7265646b616c652f7574696c2f416e6f6e796d6f7573546872656164466163746f72793b0100104d6574686f64506172616d6574657273010001720100144c6a6176612f6c616e672f52756e6e61626c653b010001740100124c6a6176612f6c616e672f5468726561643b01000d537461636b4d61705461626c65010026284c6a6176612f6c616e672f4f626a6563743b294c6a6176612f6c616e672f4f626a6563743b0100095369676e617475726501008b4c6a6176612f6c616e672f4f626a6563743b4c6a6176612f7574696c2f636f6e63757272656e742f546872656164466163746f72793b4c6a6176612f7574696c2f66756e6374696f6e2f46756e6374696f6e3c4c6a6176612f6c616e672f537472696e673b4c6a6176612f7574696c2f636f6e63757272656e742f546872656164466163746f72793b3e3b01000a536f7572636546696c6501001b416e6f6e796d6f7573546872656164466163746f72792e6a61766101000c496e6e6572436c61737365730700420100186a6176612f6c616e672f546872656164244275696c6465720100074275696c6465720100094f665669727475616c00210014000200020020002e000200120011001700000012001a001b0000000400010005001e000200300000005600020002000000162ab700012ab80007b9000d0100b500132a2bb50018b10000000200310000001200040000001500040011001000160015001700320000001600020000001600330034000000000016001a001b000100350000000501001a00000001002c002d000200300000003d0003000200000009bb0014592bb7001cb00000000200310000000600010000001b00320000001600020000000900330034000000000009001a001b000100350000000501001a00000001002300240002003000000074000200030000001c2ab400132bb9001f02004d2ab40018c6000b2c2ab40018b600252cb000000003003100000012000400000020000b002100120022001a002400320000002000030000001c0033003400000000001c003600370001000b0011003800390002003a000000080001fc001a07000800350000000501003600001041002c003b000200300000003300020002000000092a2bc00028b6002ab00000000200310000000600010000000f00320000000c00010000000900330034000000350000000501001a10000003003c00000002003d003e00000002003f00400000001200020041000800430609000e004100440609"; + + private static final Function virtualThreadFactoryFunction; + //org.redkale.util.AnonymousVirtualPoolFunction private static final String functionVirtualPoolBinary = "cafebabe0000004100610a000200030700040c000500060100106a6176612f6c616e672f4f626a6563740100063c696e69743e0100032829560a0008000907000a0c000b000c0100106a6176612f6c616e672f5468726561640100096f665669727475616c01002628294c6a6176612f6c616e672f546872656164244275696c646572244f665669727475616c3b0b000e000f0700100c001100120100226a6176612f6c616e672f546872656164244275696c646572244f665669727475616c010007666163746f727901002628294c6a6176612f7574696c2f636f6e63757272656e742f546872656164466163746f72793b0800140100075669727475616c0a001600170700180c0019001a0100106a6176612f6c616e672f537472696e67010006666f726d6174010039284c6a6176612f6c616e672f537472696e673b5b4c6a6176612f6c616e672f4f626a6563743b294c6a6176612f6c616e672f537472696e673b120000001c0c001d001e0100096e657754687265616401005c284c6a6176612f7574696c2f636f6e63757272656e742f546872656164466163746f72793b4c6a6176612f6c616e672f537472696e673b294c6a6176612f7574696c2f636f6e63757272656e742f546872656164466163746f72793b0a002000210700220c0023002401001e6a6176612f7574696c2f636f6e63757272656e742f4578656375746f72730100186e65775468726561645065725461736b4578656375746f7201004c284c6a6176612f7574696c2f636f6e63757272656e742f546872656164466163746f72793b294c6a6176612f7574696c2f636f6e63757272656e742f4578656375746f72536572766963653b0a002600270700280c0029002a01002d6f72672f7265646b616c652f7574696c2f416e6f6e796d6f75735669727475616c506f6f6c46756e6374696f6e0100056170706c7901003a284c6a6176612f6c616e672f537472696e673b294c6a6176612f7574696c2f636f6e63757272656e742f4578656375746f72536572766963653b0b002c002d07002e0c001d002f0100226a6176612f7574696c2f636f6e63757272656e742f546872656164466163746f7279010028284c6a6176612f6c616e672f52756e6e61626c653b294c6a6176612f6c616e672f5468726561643b0a000800310c003200330100077365744e616d65010015284c6a6176612f6c616e672f537472696e673b295607003501001b6a6176612f7574696c2f66756e6374696f6e2f46756e6374696f6e010004436f646501000f4c696e654e756d6265725461626c650100124c6f63616c5661726961626c655461626c650100047468697301002f4c6f72672f7265646b616c652f7574696c2f416e6f6e796d6f75735669727475616c506f6f6c46756e6374696f6e3b0100107468726561644e616d65466f726d61740100124c6a6176612f6c616e672f537472696e673b0100244c6a6176612f7574696c2f636f6e63757272656e742f546872656164466163746f72793b01000a7468726561644e616d650100104d6574686f64506172616d6574657273010026284c6a6176612f6c616e672f4f626a6563743b294c6a6176612f6c616e672f4f626a6563743b01000e6c616d626461246170706c79243001005e284c6a6176612f7574696c2f636f6e63757272656e742f546872656164466163746f72793b4c6a6176612f6c616e672f537472696e673b4c6a6176612f6c616e672f52756e6e61626c653b294c6a6176612f6c616e672f5468726561643b010001720100144c6a6176612f6c616e672f52756e6e61626c653b010001740100124c6a6176612f6c616e672f5468726561643b0100095369676e61747572650100694c6a6176612f6c616e672f4f626a6563743b4c6a6176612f7574696c2f66756e6374696f6e2f46756e6374696f6e3c4c6a6176612f6c616e672f537472696e673b4c6a6176612f7574696c2f636f6e63757272656e742f4578656375746f72536572766963653b3e3b01000a536f7572636546696c65010021416e6f6e796d6f75735669727475616c506f6f6c46756e6374696f6e2e6a617661010010426f6f7473747261704d6574686f647310002f0f06004e0a0026004f0c004100420f0600510a005200530700540c005500560100226a6176612f6c616e672f696e766f6b652f4c616d6264614d657461666163746f727901000b6d657461666163746f72790100cc284c6a6176612f6c616e672f696e766f6b652f4d6574686f6448616e646c6573244c6f6f6b75703b4c6a6176612f6c616e672f537472696e673b4c6a6176612f6c616e672f696e766f6b652f4d6574686f64547970653b4c6a6176612f6c616e672f696e766f6b652f4d6574686f64547970653b4c6a6176612f6c616e672f696e766f6b652f4d6574686f6448616e646c653b4c6a6176612f6c616e672f696e766f6b652f4d6574686f64547970653b294c6a6176612f6c616e672f696e766f6b652f43616c6c536974653b01000c496e6e6572436c61737365730700590100186a6176612f6c616e672f546872656164244275696c6465720100074275696c6465720100094f665669727475616c07005d0100256a6176612f6c616e672f696e766f6b652f4d6574686f6448616e646c6573244c6f6f6b757007005f01001e6a6176612f6c616e672f696e766f6b652f4d6574686f6448616e646c65730100064c6f6f6b75700021002600020001003400000004000100050006000100360000002f00010001000000052ab70001b10000000200370000000600010000000f00380000000c0001000000050039003a000000010029002a00020036000000720005000400000022b80007b9000d01004d2b04bd00025903121353b800154e2c2dba001b0000b8001fb00000000200370000000e000300000013000900140017001500380000002a0004000000220039003a000000000022003b003c0001000900190011003d00020017000b003e003c0003003f0000000501003b0000104100290040000200360000003300020002000000092a2bc00016b60025b00000000200370000000600010000000f00380000000c0001000000090039003a0000003f0000000501003b1000100a00410042000100360000005f000200040000000f2a2cb9002b02004e2d2bb600302db00000000200370000000e00030000001600080017000d001800380000002a00040000000f0011003d00000000000f003e003c00010000000f0043004400020008000700450046000300040047000000020048004900000002004a004b0000000c000100500003004c004d004c00570000001a000300580008005a0609000e0058005b0609005c005e00600019"; @@ -136,6 +142,7 @@ public final class Utility { ToLongFunction bufferAddrFunction0 = null; Consumer> signalShutdownConsumer0 = null; Function virtualThreadLocalFunction0 = null; + Function virtualThreadFactoryFunction0 = null; Function virtualPoolFunction0 = null; Executor virtualExecutorConsumer0 = null; @@ -164,6 +171,27 @@ public final class Utility { } } } + { //virtualThreadFactoryFunction + Class> virtualClazz1 = null; + try { + virtualClazz1 = (Class) loader.loadClass("org.redkale.util.AnonymousThreadFactory"); + } catch (Throwable t) { + } + if (virtualClazz1 == null) { + byte[] classBytes = hexToBin(functionThreadFactoryBinary); + try { + virtualClazz1 = (Class>) new ClassLoader(loader) { + public final Class loadClass(String name, byte[] b) { + return defineClass(name, b, 0, b.length); + } + }.loadClass("org.redkale.util.AnonymousThreadFactory", classBytes); + RedkaleClassLoader.putDynClass(virtualClazz1.getName(), classBytes, virtualClazz1); + RedkaleClassLoader.putReflectionDeclaredConstructors(virtualClazz1, virtualClazz1.getName()); + virtualThreadFactoryFunction0 = virtualClazz1.getConstructor(String.class).newInstance(null); + } catch (Throwable t) { + } + } + } { //virtualPoolFunction Class> virtualClazz1 = null; try { @@ -275,6 +303,7 @@ public final class Utility { signalShutdownConsumer = signalShutdownConsumer0; virtualPoolFunction = virtualPoolFunction0; virtualThreadLocalFunction = virtualThreadLocalFunction0; + virtualThreadFactoryFunction = virtualThreadFactoryFunction0; virtualExecutorConsumer = virtualExecutorConsumer0; // try { @@ -317,6 +346,43 @@ public final class Utility { return virtualThreadLocalFunction == null ? ThreadLocal.withInitial(supplier) : virtualThreadLocalFunction.apply(supplier); } + public static Function virtualFactoryFunction() { + return virtualThreadFactoryFunction; + } + + public static ThreadFactory newThreadFactory(final String name) { + if (virtualThreadFactoryFunction == null) { + if (isEmpty(name) || !name.contains("%s")) { + return (Runnable r) -> { + final Thread t = isEmpty(name) ? new Thread(r) : new Thread(r, name); + t.setDaemon(true); + return t; + }; + } else { + AtomicInteger counter = new AtomicInteger(); + return (Runnable r) -> { + final Thread t = new Thread(r, String.format(name, counter.incrementAndGet())); + t.setDaemon(true); + return t; + }; + } + } else { //虚拟线程工厂 + return virtualThreadFactoryFunction.apply(isEmpty(name) ? null : (name.contains("%s") ? String.format(name, "Virtual") : (name + "-Virtual"))); + } + } + + public static ScheduledThreadPoolExecutor newScheduledExecutor(int corePoolSize) { + return new ScheduledThreadPoolExecutor(corePoolSize, newThreadFactory(null)); + } + + public static ScheduledThreadPoolExecutor newScheduledExecutor(int corePoolSize, String name) { + return new ScheduledThreadPoolExecutor(corePoolSize, newThreadFactory(name)); + } + + public static ScheduledThreadPoolExecutor newScheduledExecutor(int corePoolSize, String name, RejectedExecutionHandler handler) { + return new ScheduledThreadPoolExecutor(corePoolSize, newThreadFactory(name), handler); + } + public static Consumer> signalShutdownConsumer() { return signalShutdownConsumer; }