diff --git a/README.md b/README.md index 4f957a7ad8c8dc2fb85b29ddb133e58c7da8a60f..a63edd0a09488cddbca60c23d9973d27e8981598 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,4 @@ -

Icon -

# PDConcurrent @@ -9,10 +7,6 @@ ![Gradle 8.10.2](https://img.shields.io/badge/Gradle-8.10.2-04303b.svg "tool") ![Apache 2](https://img.shields.io/badge/license-Apache%202-blue.svg "License") -[//]: # (-- [Java Doc](https://apidoc.gitee.com/fybug/PDConcurrent) --) - -[//]: # (-- [项目主页](https://fybug.gitee.io/projectsby/PDConcurrent.html) --) - ------------------------------------------------------------------------------- ## 简介 @@ -125,12 +119,20 @@ void main(String[] args) { 请导入其 `jar` 文件,文件在 **发行版** 或项目的 **jar** 文件夹下可以找到 -> PDConcurrent_bin.jar 为编译包 +> PDConcurrent.jar 为不包含依赖库的包 +> +> PDConcurrent_bin.jar 为包含了依赖库的包 +> +> PDConcurrent_all.jar 为包含了依赖库与源码的包 > > PDConcurrent_sources.jar 为源码包 **发行版中可以看到全部版本
项目下的 jar 文件夹是当前最新的每夜版** +依赖的同系列项目 + +- [PDUtilFunctionExpand](https://github.com/fybug/PDUtilFunctionExpand) + 可通过 **WIKI** 或者 **doc文档** 深入学习本工具 ## 分支说明 diff --git a/build.gradle b/build.gradle index 0a57b757924e7f67710424dc36c2554a632c6b5b..418869b9f41191f2d0ba9d0c1b6ef0fca07d724f 100644 --- a/build.gradle +++ b/build.gradle @@ -8,7 +8,7 @@ tasks.withType(JavaCompile).configureEach { } group 'fybug.nulll' -version = '0.1.3' +version = '0.1.4' java { toolchain { @@ -82,15 +82,41 @@ tasks.withType(Jar).configureEach { } /** 编译包 */ -tasks.register('PDConcurrent_bin', Jar) { +tasks.register('build_by', Jar) { + archiveFileName = 'PDConcurrent.jar' + archiveClassifier = 'bin' + // 打包编译输出 + from sourceSets.main.output +} + +/** 编译包 */ +tasks.register('build_bin', Jar) { archiveFileName = 'PDConcurrent_bin.jar' archiveClassifier = 'bin' // 打包编译输出 from sourceSets.main.output + from { + // implementation 相关的引入解压并打包入新的jar中 + configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } + } +} + +/** 源码包 */ +tasks.register('build_all', Jar) { + archiveFileName = 'PDConcurrent_all.jar' + archiveClassifier = 'all' + // 打包编译输出 + from sourceSets.main.output + // 打包源码 + from sourceSets.main.allSource + from { + // implementation 相关的引入解压并打包入新的jar中 + configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } + } } /** 源码包 */ -tasks.register('PDConcurrent_sources', Jar) { +tasks.register('build_sources', Jar) { archiveFileName = 'PDConcurrent_sources.jar' archiveClassifier = 'sources' // 打包源码 @@ -98,6 +124,8 @@ tasks.register('PDConcurrent_sources', Jar) { } tasks.register('release') { - dependsOn PDConcurrent_bin - dependsOn PDConcurrent_sources + dependsOn build_by + dependsOn build_all + dependsOn build_bin + dependsOn build_sources } diff --git a/jar/PDConcurrent.jar b/jar/PDConcurrent.jar new file mode 100644 index 0000000000000000000000000000000000000000..ae60b4c11e9f435e917231bbe5ecbc67b4458075 Binary files /dev/null and b/jar/PDConcurrent.jar differ diff --git a/jar/PDConcurrent_all.jar b/jar/PDConcurrent_all.jar new file mode 100644 index 0000000000000000000000000000000000000000..e2554b07403f9edca5efb5c39de7639aad759061 Binary files /dev/null and b/jar/PDConcurrent_all.jar differ diff --git a/jar/PDConcurrent_bin.jar b/jar/PDConcurrent_bin.jar index 110ed946a8e69be780d0c311d65e7ae7948dd92d..b505829e940cda7ee47ffd980a01b0cfb5b9d6d0 100644 Binary files a/jar/PDConcurrent_bin.jar and b/jar/PDConcurrent_bin.jar differ diff --git a/jar/PDConcurrent_sources.jar b/jar/PDConcurrent_sources.jar index e75492de20527190730270db4095627637c8c2a4..a8a8271e7a8200bb21780a73b8e6d962fbd50135 100644 Binary files a/jar/PDConcurrent_sources.jar and b/jar/PDConcurrent_sources.jar differ diff --git a/lib/PDUtilFunctionExpand_bin.jar b/lib/PDUtilFunctionExpand_bin.jar new file mode 100644 index 0000000000000000000000000000000000000000..e8efdb21a5952b23c1a0bcb313b4f16d2e7dc938 Binary files /dev/null and b/lib/PDUtilFunctionExpand_bin.jar differ diff --git a/src/main/java/fybug/nulll/pdconcurrent/SyLock.java b/src/main/java/fybug/nulll/pdconcurrent/SyLock.java index e21646be6aa8339513f1de0dc44d96cc6ad2ca78..732c7cb33290b32f2a56ddd1f1cff7a4dd321a77 100644 --- a/src/main/java/fybug/nulll/pdconcurrent/SyLock.java +++ b/src/main/java/fybug/nulll/pdconcurrent/SyLock.java @@ -20,7 +20,7 @@ import jakarta.validation.constraints.NotNull; * 使用 {@code new**Lock()} 的方法获取不同并发管理的实例
* * @author fybug - * @version 0.1.3 + * @version 0.1.4 * @since PDConcurrent 0.0.1 */ @SuppressWarnings("unused") diff --git a/src/main/java/fybug/nulll/pdconcurrent/fun/package-info.java b/src/main/java/fybug/nulll/pdconcurrent/fun/package-info.java deleted file mode 100644 index 67680b723059e6f53ffc398616014843f534e497..0000000000000000000000000000000000000000 --- a/src/main/java/fybug/nulll/pdconcurrent/fun/package-info.java +++ /dev/null @@ -1,8 +0,0 @@ -/** - * 功能接口包 - * - * @author fybug - * @version 0.0.4 - * @since PDConcurrent 0.0.1 - */ -package fybug.nulll.pdconcurrent.fun; \ No newline at end of file diff --git a/src/main/java/fybug/nulll/pdconcurrent/fun/tryConsumer.java b/src/main/java/fybug/nulll/pdconcurrent/fun/tryConsumer.java deleted file mode 100644 index c9dde4d5d9088c0913a78f106731895f57623f07..0000000000000000000000000000000000000000 --- a/src/main/java/fybug/nulll/pdconcurrent/fun/tryConsumer.java +++ /dev/null @@ -1,50 +0,0 @@ -package fybug.nulll.pdconcurrent.fun; -import java.util.function.Consumer; - -import jakarta.annotation.Nullable; -import jakarta.validation.constraints.NotNull; - -/** - * @param 传入的参数类型 - * - * @author fybug - * @version 0.0.2 - * @see Consumer - * @since fun 0.0.4 - */ -@SuppressWarnings("unused") -@FunctionalInterface -public -interface tryConsumer { - /** @see Consumer#accept(Object) */ - void accept(T t) throws Exception; - - /** @since 0.0.2 */ - @NotNull - default - tryConsumer andThen(@Nullable tryRunnable after) { - if ( after != null ) { - return t -> { - accept(t); - after.run(); - }; - } - return this; - } - - /** @since 0.0.2 */ - @NotNull - default - tryFunction andThen(@Nullable trySupplier after) { - if ( after != null ) { - return t -> { - accept(t); - return after.get(); - }; - } - return t -> { - accept(t); - return null; - }; - } -} diff --git a/src/main/java/fybug/nulll/pdconcurrent/fun/tryFunction.java b/src/main/java/fybug/nulll/pdconcurrent/fun/tryFunction.java deleted file mode 100644 index af64f16749793a3d890b0c0adee374954e622c2f..0000000000000000000000000000000000000000 --- a/src/main/java/fybug/nulll/pdconcurrent/fun/tryFunction.java +++ /dev/null @@ -1,41 +0,0 @@ -package fybug.nulll.pdconcurrent.fun; -import java.util.function.Function; - -import jakarta.annotation.Nullable; -import jakarta.validation.constraints.NotNull; - -/** - * @param 传入的参数类型 - * @param 返回的参数类型 - * - * @author fybug - * @version 0.0.2 - * @see Function - * @since fun 0.0.4 - */ -@SuppressWarnings("unused") -@FunctionalInterface -public -interface tryFunction { - /** @see Function#apply(Object) */ - R apply(T t) throws Exception; - - /** @since 0.0.2 */ - @NotNull - default - tryConsumer andThen(@Nullable tryConsumer after) { - if ( after != null ) - return t -> after.accept(apply(t)); - return this::apply; - } - - /** @since 0.0.2 */ - @NotNull - default - tryFunction andThen(@Nullable tryFunction after) { - if ( after != null ) - return t -> after.apply(apply(t)); - //noinspection unchecked - return (tryFunction) this; - } -} diff --git a/src/main/java/fybug/nulll/pdconcurrent/fun/tryRunnable.java b/src/main/java/fybug/nulll/pdconcurrent/fun/tryRunnable.java deleted file mode 100644 index 67330671aa2a4bf9ec54920f1d3342c08a876f69..0000000000000000000000000000000000000000 --- a/src/main/java/fybug/nulll/pdconcurrent/fun/tryRunnable.java +++ /dev/null @@ -1,75 +0,0 @@ -package fybug.nulll.pdconcurrent.fun; -import jakarta.annotation.Nullable; -import jakarta.validation.constraints.NotNull; - -/** - * @author fybug - * @version 0.0.2 - * @see Runnable - * @since fun 0.0.4 - */ -@SuppressWarnings("unused") -@FunctionalInterface -public -interface tryRunnable { - /** @see Runnable#run() */ - void run() throws Exception; - - /** @since 0.0.2 */ - @NotNull - default - tryRunnable andThen(@Nullable tryRunnable after) { - if ( after != null ) { - return () -> { - run(); - after.run(); - }; - } - return this; - } - - /** @since 0.0.2 */ - @NotNull - default - trySupplier andThen(@Nullable trySupplier after) { - if ( after != null ) { - return () -> { - run(); - return after.get(); - }; - } - return () -> { - run(); - return null; - }; - } - - /** @since 0.0.2 */ - @NotNull - default - tryRunnable andThen(@Nullable tryConsumer after) { - if ( after != null ) { - return () -> { - run(); - after.accept(null); - }; - } - return this; - } - - /** @since 0.0.2 */ - @NotNull - default - trySupplier andThen(@Nullable tryFunction after) { - if ( after != null ) { - return () -> { - run(); - return after.apply(null); - }; - } - return () -> { - run(); - return null; - }; - } -} diff --git a/src/main/java/fybug/nulll/pdconcurrent/fun/trySupplier.java b/src/main/java/fybug/nulll/pdconcurrent/fun/trySupplier.java deleted file mode 100644 index d59a835951cc9d0501d0fee065c42b8816c4b8be..0000000000000000000000000000000000000000 --- a/src/main/java/fybug/nulll/pdconcurrent/fun/trySupplier.java +++ /dev/null @@ -1,42 +0,0 @@ -package fybug.nulll.pdconcurrent.fun; -import java.util.function.Supplier; - -import jakarta.annotation.Nullable; -import jakarta.validation.constraints.NotNull; - -/** - * @param 返回的参数类型 - * - * @author fybug - * @version 0.0.2 - * @see Supplier - * @since fun 0.0.4 - */ -@SuppressWarnings("unused") -@FunctionalInterface -public -interface trySupplier { - /** @see Supplier#get() */ - R get() throws Exception; - - /** @since 0.0.2 */ - @SuppressWarnings("unused") - @NotNull - default - tryRunnable andThen(@Nullable tryConsumer after) { - if ( after != null ) - return () -> after.accept(get()); - return this::get; - } - - /** @since 0.0.2 */ - @SuppressWarnings("unused") - @NotNull - default - trySupplier andThen(@Nullable tryFunction after) { - if ( after != null ) - return () -> after.apply(get()); - //noinspection unchecked - return (trySupplier) this; - } -} diff --git a/src/main/java/fybug/nulll/pdconcurrent/i/AbstractRWSyLock.java b/src/main/java/fybug/nulll/pdconcurrent/i/AbstractRWSyLock.java new file mode 100644 index 0000000000000000000000000000000000000000..92c61fc2e703896cdcdeef7f17ab59c7c8e4be4d --- /dev/null +++ b/src/main/java/fybug/nulll/pdconcurrent/i/AbstractRWSyLock.java @@ -0,0 +1,162 @@ +package fybug.nulll.pdconcurrent.i; +import java.util.function.Function; + +import fybug.nulll.pdconcurrent.e.LockType; +import fybug.nulll.pdutilfunctionexpand.tryFunction; +import fybug.nulll.pdutilfunctionexpand.trySupplier; +import jakarta.annotation.Nullable; +import jakarta.validation.constraints.NotNull; + +/** + *

读写锁管理基本框架.

+ * 提供了读写锁实现整合接口 + * + * @author fybug + * @version 0.0.1 + * @since i 0.0.3 + */ +@SuppressWarnings("unused") +public abstract +class AbstractRWSyLock extends AbstractSyLock { + protected + AbstractRWSyLock(@NotNull LockThreadContext c) { super(c); } + + /** + * {@inheritDoc} + * + * @param lockType {@inheritDoc} + * @param run {@inheritDoc} + * @param catchby {@inheritDoc} + * @param finaby {@inheritDoc} + * @param {@inheritDoc} + * @param {@inheritDoc} + * + * @return {@inheritDoc} + * + * @throws E1 {@inheritDoc} + * @implNote 使用 {@link #lock(LockType)}、{@link #unlock()} 进行上锁解锁,因此使用两层的异常捕获避免{@code finaby}中抛出异常 + */ + @SuppressWarnings("unchecked") + @Override + protected + R lockimpl(@NotNull LockType lockType, @NotNull trySupplier run, + @Nullable tryFunction catchby, + @Nullable Function finaby) throws E1 + { + R o = null; + // 防止finally内的回调抛异常 + try { + try { + // 上锁 + lock(lockType); + // 主要内容 + o = run.get(); + } catch ( Throwable e ) { + // 异常处理 + if ( catchby != null ) + o = catchby.apply((E) e); + } finally { + // 收尾 + if ( finaby != null ) + o = finaby.apply(o); + } + } finally { + unlock(); + removeLockThreadContext(); + } + return o; + } + + /** + * {@inheritDoc} + * + * @param lockType {@inheritDoc} + * @param run {@inheritDoc} + * @param catchby {@inheritDoc} + * @param finaby {@inheritDoc} + * @param {@inheritDoc} + * @param {@inheritDoc} + * + * @return {@inheritDoc} + * + * @throws E1 {@inheritDoc} + * @implNote 使用 {@link #trylock(LockType)}、{@link #unlock()} 进行上锁解锁,因此使用两层的异常捕获避免{@code finaby}中抛出异常 + */ + @SuppressWarnings("unchecked") + @Override + protected + R trylockimpl(@NotNull LockType lockType, + @NotNull tryFunction run, + @Nullable tryFunction catchby, + @Nullable Function finaby) throws E1 + { + R o = null; + // 防止finally内的回调抛异常 + try { + try { + // 上锁 + o = run.apply(trylock(lockType)); + } catch ( Throwable e ) { + // 异常处理 + if ( catchby != null ) + o = catchby.apply((E) e); + } finally { + // 收尾 + if ( finaby != null ) + o = finaby.apply(o); + } + } finally { + unlock(); + removeLockThreadContext(); + } + return o; + } + + /** + * 上锁函数 + *

+ * 按照设置的上下文参数要求可能会因为线程被中断而抛出{@link InterruptedException}异常 + * + * @param lockType 锁类型 + * + * @implSpec 在此处实现上锁功能,实现时应该支持根据上下文选择是否使用可以被线程中断的上锁方式 + */ + protected abstract + void lock(@NotNull LockType lockType); + + /** + * 尝试上锁函数 + * + * @param lockType 锁类型 + * + * @return 是否成功上锁 + * + * @implSpec 在此处实现尝试上锁功能,实现时应该支持上下文参数 + */ + protected abstract + boolean trylock(@NotNull LockType lockType); + + /** + * 解锁函数 + * + * @implSpec 在此处实现解锁功能,解锁的类型按照最后上锁的类型处理 + */ + public abstract + void unlock(); + + /** + * 检查锁是否被占用 + * + * @return 是否被占用 + */ + public abstract + boolean isLocked(); + + /** + * 检查当前线程是否持有锁 + * + * @return 当前线程是否持有锁 + */ + public abstract + boolean isLockedCurrentThread(); +} diff --git a/src/main/java/fybug/nulll/pdconcurrent/i/AbstractSyLock.java b/src/main/java/fybug/nulll/pdconcurrent/i/AbstractSyLock.java index f4dba533f5f736c24e3536589505c54df572b0fb..130072ed6207e938ded65812d37dcb1f08998015 100644 --- a/src/main/java/fybug/nulll/pdconcurrent/i/AbstractSyLock.java +++ b/src/main/java/fybug/nulll/pdconcurrent/i/AbstractSyLock.java @@ -1,23 +1,85 @@ package fybug.nulll.pdconcurrent.i; +import java.util.concurrent.TimeUnit; import java.util.function.Function; import fybug.nulll.pdconcurrent.SyLock; import fybug.nulll.pdconcurrent.e.LockType; -import fybug.nulll.pdconcurrent.fun.tryFunction; -import fybug.nulll.pdconcurrent.fun.trySupplier; +import fybug.nulll.pdutilfunctionexpand.tryFunction; +import fybug.nulll.pdutilfunctionexpand.trySupplier; import jakarta.annotation.Nullable; import jakarta.validation.constraints.NotNull; +import lombok.Getter; +import lombok.Setter; /** - *

读写锁管理基本框架.

+ *

锁管理基本框架.

+ * 提供了锁行为的实现整合
+ * 支持通过主动设置当前线程的上下文参数{@link LockThreadContext}改变锁行为甚至当前线程使用的锁对象,默认使用{@link #defaultLockThreadContext}
+ * 需要注意的是,设置为{@link #defaultLockThreadContext}的对象不应该被修改,否则可能会导致没有独立设置上下文的锁发生异常,更新{@link #defaultLockThreadContext}时也应该传入新的对象,至少不能是同一个对象 * * @author fybug * @version 0.0.1 - * @since i 0.0.1 + * @see LockThreadContext + * @since i 0.0.3 */ @SuppressWarnings("unused") public abstract -class AbstractSyLock implements SyLock { +class AbstractSyLock implements SyLock { + /** 线程的锁上下文 */ + @NotNull protected final ThreadLocal> lockThreadContext = new ThreadLocal<>(); + /** 默认锁上下文 */ + @NotNull protected LockThreadContext defaultLockThreadContext; + + protected + AbstractSyLock(@NotNull LockThreadContext c) { this.defaultLockThreadContext = c; } + + /** + * 锁运行具体实现 + *

+ * {@link #lock(LockType, trySupplier, Function)}与{@link #lock(LockType, trySupplier, Function, Function)}底层实现,要求同时覆盖两个接口的规范,同时应该支持上下文参数{@link LockThreadContext}
+ * 通过{@code catchby}传入的值决定异常的处理 + * + * @param lockType 锁类型 + * @param run 带返回的回调 + * @param catchby 进入catch块后的回调,传入当前异常,如果需要无视并不抛出异常则传入{@code null} + * @param finaby 进入finally块后的回调,传入前一个回调的返回值,遇到异常传入{@code null} + * @param 要返回的数据类型 + * @param 运行时异常类型 + * + * @return 回调返回的内容,中途二次抛出异常时不返回 + * + * @throws E1 二次抛出的异常类型 + * @implSpec {@code catchby}传入为{@code null}时应该无视并不抛出异常,同时给{@code finaby}的值为{@code null} + */ + abstract protected + R lockimpl(@NotNull LockType lockType, @NotNull trySupplier run, + @Nullable tryFunction catchby, + @Nullable Function finaby) throws E1; + + /** + * 尝试上锁运行具体实现 + *

+ * {@link #trylock(LockType, tryFunction, Function)}与{@link #trylock(LockType, tryFunction, Function, Function)}底层实现,要求同时覆盖两个接口的规范,同时应该支持上下文参数{@link LockThreadContext}
+ * 通过{@code catchby}传入的值决定异常的处理 + * + * @param lockType 锁类型 + * @param run 带返回的回调,传入参数是否获取到锁 + * @param catchby 进入catch块后的回调,传入当前异常,如果需要无视并不抛出异常则传入{@code null} + * @param finaby 进入finally块后的回调,传入前一个回调的返回值,遇到异常传入{@code null} + * @param 要返回的数据类型 + * @param 运行时异常类型 + * + * @return 回调返回的内容,中途二次抛出异常时不返回 + * + * @throws E1 二次抛出的异常类型 + * @implSpec {@code catchby}传入为{@code null}时应该无视并不抛出异常,同时给{@code finaby}的值为{@code null} + */ + abstract protected + R trylockimpl(@NotNull LockType lockType, + @NotNull tryFunction run, + @Nullable tryFunction catchby, + @Nullable Function finaby) throws E1; + /** * {@inheritDoc} * @@ -26,38 +88,17 @@ class AbstractSyLock implements SyLock { * @param catchby {@inheritDoc} * @param finaby {@inheritDoc} * @param {@inheritDoc} + * @param {@inheritDoc} * * @return {@inheritDoc} * - * @implNote 使用 {@link #lock(LockType)} 与 {@link #unlock()} 方法实现上锁与解锁 + * @see #lockimpl(LockType, trySupplier, tryFunction, Function) */ @Override public - R lock(@NotNull LockType lockType, @NotNull trySupplier run, @Nullable Function catchby, - @Nullable Function finaby) - { - R o = null; - // 防止finally内的回调抛异常 - try { - try { - // 上锁 - lock(lockType); - // 主要内容 - o = run.get(); - } catch ( Exception e ) { - // 异常处理 - if ( catchby != null ) - o = catchby.apply(e); - } finally { - // 收尾 - if ( finaby != null ) - o = finaby.apply(o); - } - } finally { - unlock(); - } - return o; - } + R lock(@NotNull LockType lockType, @NotNull trySupplier run, + @Nullable Function catchby, @Nullable Function finaby) + { return lockimpl(lockType, run, catchby == null ? null : catchby::apply, finaby); } /** * {@inheritDoc} @@ -66,32 +107,18 @@ class AbstractSyLock implements SyLock { * @param run {@inheritDoc} * @param finaby {@inheritDoc} * @param {@inheritDoc} + * @param {@inheritDoc} * * @return {@inheritDoc} * - * @implNote 使用 {@link #lock(LockType)} 与 {@link #unlock()} 方法实现上锁与解锁 + * @throws E {@inheritDoc} + * @see #lockimpl(LockType, trySupplier, tryFunction, Function) */ @Override public - R lock(@NotNull LockType lockType, @NotNull trySupplier run, @Nullable Function finaby) throws Exception { - R o = null; - // 防止finally内的回调抛异常 - try { - try { - // 上锁 - lock(lockType); - // 主要内容 - o = run.get(); - } finally { - // 收尾 - if ( finaby != null ) - o = finaby.apply(o); - } - } finally { - unlock(); - } - return o; - } + R lock(@NotNull LockType lockType, @NotNull trySupplier run, + @Nullable Function finaby) throws E + { return lockimpl(lockType, run, e -> { throw e; }, finaby); } /** * {@inheritDoc} @@ -101,36 +128,17 @@ class AbstractSyLock implements SyLock { * @param catchby {@inheritDoc} * @param finaby {@inheritDoc} * @param {@inheritDoc} + * @param {@inheritDoc} * * @return {@inheritDoc} * - * @implNote 使用 {@link #trylock(LockType)} 与 {@link #unlock()} 方法实现上锁与解锁 + * @see #trylockimpl(LockType, tryFunction, tryFunction, Function) */ @Override public - R trylock(@NotNull LockType lockType, @NotNull tryFunction run, @Nullable Function catchby, - @Nullable Function finaby) - { - R o = null; - // 防止finally内的回调抛异常 - try { - try { - // 上锁 - o = run.apply(trylock(lockType)); - } catch ( Exception e ) { - // 异常处理 - if ( catchby != null ) - o = catchby.apply(e); - } finally { - // 收尾 - if ( finaby != null ) - o = finaby.apply(o); - } - } finally { - unlock(); - } - return o; - } + R trylock(@NotNull LockType lockType, @NotNull tryFunction run, + @Nullable Function catchby, @Nullable Function finaby) + { return trylockimpl(lockType, run, catchby == null ? null : catchby::apply, finaby); } /** * {@inheritDoc} @@ -139,78 +147,121 @@ class AbstractSyLock implements SyLock { * @param run {@inheritDoc} * @param finaby {@inheritDoc} * @param {@inheritDoc} + * @param {@inheritDoc} * * @return {@inheritDoc} * - * @throws Exception {@inheritDoc} - * @implNote 使用 {@link #trylock(LockType)} 与 {@link #unlock()} 方法实现上锁与解锁 + * @throws E {@inheritDoc} + * @see #trylockimpl(LockType, tryFunction, tryFunction, Function) */ @Override public - R trylock(@NotNull LockType lockType, @NotNull tryFunction run, @Nullable Function finaby) - throws Exception - { - R o = null; - // 防止finally内的回调抛异常 - try { - try { - // 上锁 - o = run.apply(trylock(lockType)); - } finally { - // 收尾 - if ( finaby != null ) - o = finaby.apply(o); - } - } finally { - unlock(); - } - return o; - } + R trylock(@NotNull LockType lockType, @NotNull tryFunction run, + @Nullable Function finaby) throws E + { return trylockimpl(lockType, run, e -> { throw e; }, finaby); } /** - * 上锁函数 + * 更新默认锁上下文参数 + *

+ * 该方法是非线程安全的,因为每次执行前都会先保存默认参数的引用,更新时应该传入一个新的参数对象,至少不能是同一个对象 * - * @param lockType 锁类型 - * - * @throws Exception 可能抛出的异常 - * @implSpec 在此处实现上锁功能 + * @param lockThreadContext 新的默认上下文参数 */ - protected abstract - void lock(@NotNull LockType lockType) throws Exception; + public + void setDefaultLockThreadContext(@NotNull LockThreadContext lockThreadContext) { + this.defaultLockThreadContext = lockThreadContext; + } + + /** 获取当前默认上下文参数 */ + @NotNull + public + LockThreadContext defaultLockThreadContext() { return defaultLockThreadContext; } /** - * 尝试上锁函数 - * - * @param lockType 锁类型 - * - * @return 是否成功上锁 - * - * @implSpec 在此处实现尝试上锁功能 + * 获取当前线程的上下文参数 + *

+ * 如果没有设置独立的上下文参数,则使用{@link #defaultLockThreadContext} */ - protected abstract - boolean trylock(@NotNull LockType lockType); + @NotNull + public + LockThreadContext getLockThreadContext() { + var c = lockThreadContext.get(); + if ( c == null ) + return defaultLockThreadContext; + return c; + } /** - * 解锁函数 - * - * @implSpec 在此处实现解锁功能,解锁的类型按照最后上锁的类型处理 + * 设置当前线程上下文参数 + *

+ * 要求不在锁内使用,否则可能会出现异常 */ - public abstract - void unlock(); + public + void setLockThreadContext(@NotNull LockThreadContext c) { lockThreadContext.set(c); } + + /** + * 移除当前上下文参数 + *

+ * 通常情况下执行结束后会自动移除,但如果手动设置后并没有执行锁的情况下才需要手动移除 + */ + public + void removeLockThreadContext() { lockThreadContext.remove(); } /** - * 检查锁是否被占用 + *

当前线程的锁上下文.

+ * 根据该参数可以改变使用的锁对象,更改当前对象支持的上锁方式,与参数上锁的超时时间等
+ * 参数上锁时间为{@code null}时为不使用带超时功能的参数上锁 + * + * @param 用于上锁的对象 * - * @return 是否被占用 + * @author fybug + * @version 0.0.1 + * @since AbstractSyLock 0.0.1 */ - public abstract - boolean isLocked(); + public static + class LockThreadContext { + /** 本次锁对象 */ + @Setter @Getter @NotNull protected T lock; + /** + * 是否支持线程中断 + * + * @see InterruptedException + */ + @Setter @Getter protected boolean interruptiblyLock; + /** + * 尝试锁时间限制 + *

+ * 传入为{@code null}时为不使用超时功能 + * + * @see InterruptedException + */ + @Setter @Getter @Nullable protected Time tryTimeout; + + public + LockThreadContext(@NotNull T lock, boolean interruptiblyLock, @Nullable Time tryTimeout) { + this.lock = lock; + this.interruptiblyLock = interruptiblyLock; + this.tryTimeout = tryTimeout; + } + } /** - * 检查当前线程是否持有锁 + *

时间对象.

+ * 用于记录时间,支持设置时间类型 * - * @return 当前线程是否持有锁 + * @author fybug + * @version 0.0.1 + * @since AbstractSyLock 0.0.1 */ - public abstract - boolean isLockedCurrentThread(); + public static + class Time { + @Getter protected long timeout; + @Getter @NotNull protected TimeUnit unit; + + public + Time(long timeout, @NotNull TimeUnit unit) { + this.timeout = timeout; + this.unit = unit; + } + } } diff --git a/src/main/java/fybug/nulll/pdconcurrent/i/Lock.java b/src/main/java/fybug/nulll/pdconcurrent/i/Lock.java index de52725a072334de92ced7e77c6df3fa28550abc..0ab3c2463bd8e40ee2b5dd2e5a39c2d7024b9853 100644 --- a/src/main/java/fybug/nulll/pdconcurrent/i/Lock.java +++ b/src/main/java/fybug/nulll/pdconcurrent/i/Lock.java @@ -1,10 +1,8 @@ package fybug.nulll.pdconcurrent.i; -import java.util.function.Consumer; import java.util.function.Function; import fybug.nulll.pdconcurrent.e.LockType; -import fybug.nulll.pdconcurrent.fun.tryRunnable; -import fybug.nulll.pdconcurrent.fun.trySupplier; +import fybug.nulll.pdutilfunctionexpand.trySupplier; import jakarta.annotation.Nullable; import jakarta.validation.constraints.NotNull; @@ -32,35 +30,15 @@ interface Lock { * @param catchby 进入catch块后的回调,传入当前异常 * @param finaby 进入finally块后的回调,传入前两个回调的返回值 * @param 要返回的数据类型 + * @param 运行时异常类型 * * @return 回调返回的内容 * * @implSpec 如果有传入 {@code finaby} 回调则返回值由{@code finaby}主导,传入{@code finaby}的值根据是否发生异常传入{@code run}的返回值或{@code catchby}的返回值
* 任意一个回调为空时直接穿透,使用上一个正确执行的值进行传递或者返回,传递值应默认为{@code null}用于应对{@code catchby}和{@code finaby}都为空但是发生了异常的情况 */ - R lock(@NotNull LockType lockType, @NotNull trySupplier run, @Nullable Function catchby, - @Nullable Function finaby); - - /** - * 使用锁执行指定回调 - *

- * {@link #lock(LockType, trySupplier, Function, Function)}的无返回变体 - */ - default - void lock(@NotNull LockType lockType, @NotNull tryRunnable run, @Nullable Consumer catchby, - @Nullable Runnable finaby) - { - lock(lockType, () -> { - run.run(); - return null; - }, catchby == null ? null : e -> { - catchby.accept(e); - return null; - }, finaby == null ? null : _ -> { - finaby.run(); - return null; - }); - } + R lock(@NotNull LockType lockType, @NotNull trySupplier run, + @Nullable Function catchby, @Nullable Function finaby); /** * 使用锁执行指定回调 @@ -72,28 +50,14 @@ interface Lock { * @param run 带返回的回调 * @param finaby 进入finally块后的回调,传入前一个回调的返回值,遇到异常传入{@code null} * @param 要返回的数据类型 + * @param 运行时异常类型 * * @return 回调返回的内容,遇到异常不返回 * - * @throws Exception 异常类型根据实际运行时回调抛出决定 + * @throws E 异常类型根据实际运行时回调抛出决定 * @implSpec 如果有传入 {@code finaby} 回调则返回值由{@code finaby}主导,传入{@code finaby}的值根据是否发生异常传入{@code run}的返回值或{@code null}
* 任意一个回调为空时直接穿透,使用上一个正确执行的值进行传递或者返回,发生异常会执行{@code finaby}但是不会返回内容 */ - R lock(@NotNull LockType lockType, @NotNull trySupplier run, @Nullable Function finaby) throws Exception; - - /** - * 使用锁执行指定回调 - *

- * {@link #lock(LockType, trySupplier, Function)}的无返回变体 - */ - default - void lock(@NotNull LockType lockType, @NotNull tryRunnable run, @Nullable Runnable finaby) throws Exception { - lock(lockType, () -> { - run.run(); - return null; - }, finaby == null ? null : _ -> { - finaby.run(); - return null; - }); - } + R lock(@NotNull LockType lockType, @NotNull trySupplier run, + @Nullable Function finaby) throws E; } diff --git a/src/main/java/fybug/nulll/pdconcurrent/i/ReadLock.java b/src/main/java/fybug/nulll/pdconcurrent/i/ReadLock.java index 1824694a640efd5a1b72e203c6109089eabd0b9f..53943245e61ad426b045ed6c12727bbb7057ff8a 100644 --- a/src/main/java/fybug/nulll/pdconcurrent/i/ReadLock.java +++ b/src/main/java/fybug/nulll/pdconcurrent/i/ReadLock.java @@ -1,11 +1,9 @@ package fybug.nulll.pdconcurrent.i; -import java.util.function.Consumer; import java.util.function.Function; import fybug.nulll.pdconcurrent.e.LockType; -import fybug.nulll.pdconcurrent.fun.tryRunnable; -import fybug.nulll.pdconcurrent.fun.trySupplier; import fybug.nulll.pdconcurrent.i.simple.LockSimple; +import fybug.nulll.pdutilfunctionexpand.trySupplier; import jakarta.annotation.Nullable; import jakarta.validation.constraints.NotNull; @@ -28,33 +26,16 @@ interface ReadLock extends LockSimple { * {@link #lock(LockType, trySupplier, Function, Function)}指定读锁的变种 */ default - R read(@NotNull trySupplier run, @Nullable Function catchby, @Nullable Function finaby) + R read(@NotNull trySupplier run, @Nullable Function catchby, + @Nullable Function finaby) { return lock(LockType.READ, run, catchby, finaby); } - /** - * 使用读锁执行指定回调 - *

- * {@link #lock(LockType, tryRunnable, Consumer, Runnable)}指定读锁的变种 - */ - default - void read(@NotNull tryRunnable run, @Nullable Consumer catchby, @Nullable Runnable finaby) - { lock(LockType.READ, run, catchby, finaby); } - /** * 使用读锁执行指定回调 *

* {@link #lock(LockType, trySupplier, Function)}指定读锁的变种 */ default - R read(@NotNull trySupplier run, @Nullable Function finaby) throws Exception + R read(@NotNull trySupplier run, @Nullable Function finaby) throws E { return lock(LockType.READ, run, finaby); } - - /** - * 使用读锁执行指定回调 - *

- * {@link #lock(LockType, tryRunnable, Runnable)}指定读锁的变种 - */ - default - void read(@NotNull tryRunnable run, @Nullable Runnable finaby) throws Exception - { lock(LockType.READ, run, finaby); } } diff --git a/src/main/java/fybug/nulll/pdconcurrent/i/TryLock.java b/src/main/java/fybug/nulll/pdconcurrent/i/TryLock.java index 73c60439b441914f200db03fcd56c62d1d341a51..c49cd174e95320b64e43dd552426b661348e4cab 100644 --- a/src/main/java/fybug/nulll/pdconcurrent/i/TryLock.java +++ b/src/main/java/fybug/nulll/pdconcurrent/i/TryLock.java @@ -1,11 +1,9 @@ package fybug.nulll.pdconcurrent.i; import java.util.concurrent.locks.ReentrantLock; -import java.util.function.Consumer; import java.util.function.Function; import fybug.nulll.pdconcurrent.e.LockType; -import fybug.nulll.pdconcurrent.fun.tryConsumer; -import fybug.nulll.pdconcurrent.fun.tryFunction; +import fybug.nulll.pdutilfunctionexpand.tryFunction; import jakarta.annotation.Nullable; import jakarta.validation.constraints.NotNull; @@ -31,6 +29,7 @@ interface TryLock { * @param catchby 进入catch块后的回调,传入当前异常 * @param finaby 进入finally块后的回调,传入前两个回调的返回值 * @param 要返回的数据类型 + * @param 运行时异常类型 * * @return 回调返回的内容 * @@ -38,29 +37,8 @@ interface TryLock { * 如果有传入 {@code finaby} 回调则返回值由{@code finaby}主导,传入{@code finaby}的值根据是否发生异常传入{@code run}的返回值或{@code catchby}的返回值
* 任意一个回调为空时直接穿透,使用上一个正确执行的值进行传递或者返回,传递值应默认为{@code null}用于应对{@code catchby}和{@code finaby}都为空但是发生了异常的情况 */ - R trylock(@NotNull LockType lockType, @NotNull tryFunction run, @Nullable Function catchby, - @Nullable Function finaby); - - /** - * 尝试使用锁执行指定回调 - *

- * {@link #trylock(LockType, tryFunction, Function, Function)}的无返回变体 - */ - default - void trylock(@NotNull LockType lockType, @NotNull tryConsumer run, @Nullable Consumer catchby, - @Nullable Runnable finaby) - { - trylock(lockType, b -> { - run.accept(b); - return null; - }, catchby == null ? null : e -> { - catchby.accept(e); - return null; - }, finaby == null ? null : _ -> { - finaby.run(); - return null; - }); - } + R trylock(@NotNull LockType lockType, @NotNull tryFunction run, + @Nullable Function catchby, @Nullable Function finaby); /** * 尝试使用锁执行指定回调 @@ -72,30 +50,15 @@ interface TryLock { * @param run 带返回的回调,传入参数是否获取到锁 * @param finaby 进入finally块后的回调,传入前两个回调的返回值,遇到异常传入{@code null} * @param 要返回的数据类型 + * @param 运行时异常类型 * * @return 回调返回的内容,遇到异常不返回 * - * @throws Exception 异常类型根据实际运行时回调抛出决定 + * @throws E 异常类型根据实际运行时回调抛出决定 * @implSpec 该方法实现时应尽量使用如 {@link ReentrantLock#tryLock()} 之类的方法获取锁,并将是否成功获取传入{@code run}回调中
* 如果有传入 {@code finaby} 回调则返回值由{@code finaby}主导,传入{@code finaby}的值根据是否发生异常传入{@code run}的返回值或{@code catchby}的返回值
* 任意一个回调为空时直接穿透,使用上一个正确执行的值进行传递或者返回,传递值应默认为{@code null}用于应对{@code catchby}和{@code finaby}都为空但是发生了异常的情况 */ - R trylock(@NotNull LockType lockType, @NotNull tryFunction run, @Nullable Function finaby) - throws Exception; - - /** - * 尝试使用锁执行指定回调 - *

- * {@link #trylock(LockType, tryFunction, Function)}的无返回变体 - */ - default - void trylock(@NotNull LockType lockType, @NotNull tryConsumer run, @Nullable Runnable finaby) throws Exception { - trylock(lockType, b -> { - run.accept(b); - return null; - }, finaby == null ? null : _ -> { - finaby.run(); - return null; - }); - } + R trylock(@NotNull LockType lockType, @NotNull tryFunction run, + @Nullable Function finaby) throws E; } diff --git a/src/main/java/fybug/nulll/pdconcurrent/i/TryReadLock.java b/src/main/java/fybug/nulll/pdconcurrent/i/TryReadLock.java index 2f8b22dc016ecdfc6cbb4a6fc7789a1c579cbfe0..33de1877a7acdaf86ea3bc6f2b3158bc79053b56 100644 --- a/src/main/java/fybug/nulll/pdconcurrent/i/TryReadLock.java +++ b/src/main/java/fybug/nulll/pdconcurrent/i/TryReadLock.java @@ -1,11 +1,9 @@ package fybug.nulll.pdconcurrent.i; -import java.util.function.Consumer; import java.util.function.Function; import fybug.nulll.pdconcurrent.e.LockType; -import fybug.nulll.pdconcurrent.fun.tryConsumer; -import fybug.nulll.pdconcurrent.fun.tryFunction; import fybug.nulll.pdconcurrent.i.simple.TryLockSimple; +import fybug.nulll.pdutilfunctionexpand.tryFunction; import jakarta.annotation.Nullable; import jakarta.validation.constraints.NotNull; @@ -28,34 +26,16 @@ interface TryReadLock extends TryLockSimple { * {@link #trylock(LockType, tryFunction, Function, Function)}指定读锁的变种 */ default - R tryread(@NotNull tryFunction run, @Nullable Function catchby, - @Nullable Function finaby) + R tryread(@NotNull tryFunction run, @Nullable Function catchby, + @Nullable Function finaby) { return trylock(LockType.READ, run, catchby, finaby); } - /** - * 尝试使用读锁执行指定回调 - *

- * {@link #trylock(LockType, tryConsumer, Consumer, Runnable)}指定读锁的变种 - */ - default - void tryread(@NotNull tryConsumer run, @Nullable Consumer catchby, @Nullable Runnable finaby) - { trylock(LockType.READ, run, catchby, finaby); } - /** * 尝试使用读锁执行指定回调 *

* {@link #trylock(LockType, tryFunction, Function)}指定读锁的变种 */ default - R tryread(@NotNull tryFunction run, @Nullable Function finaby) throws Exception + R tryread(@NotNull tryFunction run, @Nullable Function finaby) throws E { return trylock(LockType.READ, run, finaby); } - - /** - * 尝试使用读锁执行指定回调 - *

- * {@link #trylock(LockType, tryConsumer, Runnable)}指定读锁的变种 - */ - default - void tryread(@NotNull tryConsumer run, @Nullable Runnable finaby) throws Exception - { trylock(LockType.READ, run, finaby); } } diff --git a/src/main/java/fybug/nulll/pdconcurrent/i/TryWriteLock.java b/src/main/java/fybug/nulll/pdconcurrent/i/TryWriteLock.java index 75f55b7900ae4794972e589240b582618bea8516..45002f54259a075c3322fd3a23e0eaf4e5dfb45b 100644 --- a/src/main/java/fybug/nulll/pdconcurrent/i/TryWriteLock.java +++ b/src/main/java/fybug/nulll/pdconcurrent/i/TryWriteLock.java @@ -1,11 +1,9 @@ package fybug.nulll.pdconcurrent.i; -import java.util.function.Consumer; import java.util.function.Function; import fybug.nulll.pdconcurrent.e.LockType; -import fybug.nulll.pdconcurrent.fun.tryConsumer; -import fybug.nulll.pdconcurrent.fun.tryFunction; import fybug.nulll.pdconcurrent.i.simple.TryLockSimple; +import fybug.nulll.pdutilfunctionexpand.tryFunction; import jakarta.annotation.Nullable; import jakarta.validation.constraints.NotNull; @@ -28,34 +26,16 @@ interface TryWriteLock extends TryLockSimple { * {@link #trylock(LockType, tryFunction, Function, Function)}指定写锁的变种 */ default - R trywrite(@NotNull tryFunction run, @Nullable Function catchby, - @Nullable Function finaby) + R trywrite(@NotNull tryFunction run, @Nullable Function catchby, + @Nullable Function finaby) { return trylock(LockType.WRITE, run, catchby, finaby); } - /** - * 尝试使用写锁执行指定回调 - *

- * {@link #trylock(LockType, tryConsumer, Consumer, Runnable)}指定写锁的变种 - */ - default - void trywrite(@NotNull tryConsumer run, @Nullable Consumer catchby, @Nullable Runnable finaby) - { trylock(LockType.WRITE, run, catchby, finaby); } - /** * 尝试使用写锁执行指定回调 *

* {@link #trylock(LockType, tryFunction, Function)}指定写锁的变种 */ default - R trywrite(@NotNull tryFunction run, @Nullable Function finaby) throws Exception + R trywrite(@NotNull tryFunction run, @Nullable Function finaby) throws E { return trylock(LockType.WRITE, run, finaby); } - - /** - * 尝试使用写锁执行指定回调 - *

- * {@link #trylock(LockType, tryConsumer, Runnable)}指定写锁的变种 - */ - default - void trywrite(@NotNull tryConsumer run, @Nullable Runnable finaby) throws Exception - { trylock(LockType.WRITE, run, finaby); } } diff --git a/src/main/java/fybug/nulll/pdconcurrent/i/WriteLock.java b/src/main/java/fybug/nulll/pdconcurrent/i/WriteLock.java index 5b6f57479f27a0b2a887e632ddfd94c92d8893e4..5021880e7dbe6b5a93a7ce6772ce498c9774079f 100644 --- a/src/main/java/fybug/nulll/pdconcurrent/i/WriteLock.java +++ b/src/main/java/fybug/nulll/pdconcurrent/i/WriteLock.java @@ -1,11 +1,9 @@ package fybug.nulll.pdconcurrent.i; -import java.util.function.Consumer; import java.util.function.Function; import fybug.nulll.pdconcurrent.e.LockType; -import fybug.nulll.pdconcurrent.fun.tryRunnable; -import fybug.nulll.pdconcurrent.fun.trySupplier; import fybug.nulll.pdconcurrent.i.simple.LockSimple; +import fybug.nulll.pdutilfunctionexpand.trySupplier; import jakarta.annotation.Nullable; import jakarta.validation.constraints.NotNull; @@ -28,33 +26,16 @@ interface WriteLock extends LockSimple { * {@link #lock(LockType, trySupplier, Function, Function)}指定写锁的变种 */ default - R write(@NotNull trySupplier run, @Nullable Function catchby, @Nullable Function finaby) + R write(@NotNull trySupplier run, @Nullable Function catchby, + @Nullable Function finaby) { return lock(LockType.WRITE, run, catchby, finaby); } - /** - * 使用写锁执行指定回调 - *

- * {@link #lock(LockType, tryRunnable, Consumer, Runnable)}指定写锁的变种 - */ - default - void write(@NotNull tryRunnable run, @Nullable Consumer catchby, @Nullable Runnable finaby) - { lock(LockType.WRITE, run, catchby, finaby); } - /** * 使用写锁执行指定回调 *

* {@link #lock(LockType, trySupplier, Function)}指定写锁的变种 */ default - R write(@NotNull trySupplier run, @Nullable Function finaby) throws Exception + R write(@NotNull trySupplier run, @Nullable Function finaby) throws E { return lock(LockType.WRITE, run, finaby); } - - /** - * 使用写锁执行指定回调 - *

- * {@link #lock(LockType, tryRunnable, Runnable)}指定写锁的变种 - */ - default - void write(@NotNull tryRunnable run, @Nullable Runnable finaby) throws Exception - { lock(LockType.WRITE, run, finaby); } } diff --git a/src/main/java/fybug/nulll/pdconcurrent/i/package-info.java b/src/main/java/fybug/nulll/pdconcurrent/i/package-info.java index 04495588a4792675defc03937e02c2f636fa6f77..6e502979bea6172e9f3a79d9e78db50cb8a94e3a 100644 --- a/src/main/java/fybug/nulll/pdconcurrent/i/package-info.java +++ b/src/main/java/fybug/nulll/pdconcurrent/i/package-info.java @@ -3,7 +3,7 @@ * 提供基础功能接口与部分功能框架实现 * * @author fybug - * @version 0.0.2 + * @version 0.0.3 * @since PDConcurrent 0.1.2 */ package fybug.nulll.pdconcurrent.i; \ No newline at end of file diff --git a/src/main/java/fybug/nulll/pdconcurrent/i/simple/LockSimple.java b/src/main/java/fybug/nulll/pdconcurrent/i/simple/LockSimple.java index 639d29128f3d0768b76afeb68331e77e4510d902..8d8dbcaa21538bfb1d1dc2d142937984e1ae159c 100644 --- a/src/main/java/fybug/nulll/pdconcurrent/i/simple/LockSimple.java +++ b/src/main/java/fybug/nulll/pdconcurrent/i/simple/LockSimple.java @@ -1,10 +1,12 @@ package fybug.nulll.pdconcurrent.i.simple; +import java.util.function.Consumer; import java.util.function.Function; import fybug.nulll.pdconcurrent.e.LockType; -import fybug.nulll.pdconcurrent.fun.tryRunnable; -import fybug.nulll.pdconcurrent.fun.trySupplier; import fybug.nulll.pdconcurrent.i.Lock; +import fybug.nulll.pdutilfunctionexpand.tryRunnable; +import fybug.nulll.pdutilfunctionexpand.trySupplier; +import jakarta.annotation.Nullable; import jakarta.validation.constraints.NotNull; /** @@ -16,13 +18,52 @@ import jakarta.validation.constraints.NotNull; */ public interface LockSimple extends Lock { + /** + * 使用锁执行指定回调 + *

+ * {@link #lock(LockType, trySupplier, Function, Function)}的无返回变体 + */ + default + void lock(@NotNull LockType lockType, @NotNull tryRunnable run, @Nullable Consumer catchby, + @Nullable Runnable finaby) + { + lock(lockType, () -> { + run.run(); + return null; + }, catchby == null ? null : (E e) -> { + catchby.accept(e); + return null; + }, finaby == null ? null : _ -> { + finaby.run(); + return null; + }); + } + + /** + * 使用锁执行指定回调 + *

+ * {@link #lock(LockType, trySupplier, Function)}的无返回变体 + */ + default + void lock(@NotNull LockType lockType, @NotNull tryRunnable run, @Nullable Runnable finaby) + throws E + { + lock(lockType, () -> { + run.run(); + return null; + }, finaby == null ? null : _ -> { + finaby.run(); + return null; + }); + } + /** * 使用锁执行指定回调 *

* {@link #lock(LockType, trySupplier, Function)}的简易变体 */ default - R lock(@NotNull LockType lockType, @NotNull trySupplier run) throws Exception + R lock(@NotNull LockType lockType, @NotNull trySupplier run) throws E { return lock(lockType, run, null); } /** @@ -31,6 +72,6 @@ interface LockSimple extends Lock { * {@link #lock(LockType, tryRunnable, Runnable)}的简易变体 */ default - void lock(@NotNull LockType lockType, @NotNull tryRunnable run) throws Exception + void lock(@NotNull LockType lockType, @NotNull tryRunnable run) throws E { lock(lockType, run, null); } } diff --git a/src/main/java/fybug/nulll/pdconcurrent/i/simple/ReadLockSimple.java b/src/main/java/fybug/nulll/pdconcurrent/i/simple/ReadLockSimple.java index 8515240bb3d6d1b4a02e49dc173c987cd3d1fa37..49aa85a102dc5c25753a4e648acde2328d23f087 100644 --- a/src/main/java/fybug/nulll/pdconcurrent/i/simple/ReadLockSimple.java +++ b/src/main/java/fybug/nulll/pdconcurrent/i/simple/ReadLockSimple.java @@ -1,8 +1,11 @@ package fybug.nulll.pdconcurrent.i.simple; +import java.util.function.Consumer; + import fybug.nulll.pdconcurrent.e.LockType; -import fybug.nulll.pdconcurrent.fun.tryRunnable; -import fybug.nulll.pdconcurrent.fun.trySupplier; import fybug.nulll.pdconcurrent.i.ReadLock; +import fybug.nulll.pdutilfunctionexpand.tryRunnable; +import fybug.nulll.pdutilfunctionexpand.trySupplier; +import jakarta.annotation.Nullable; import jakarta.validation.constraints.NotNull; /** @@ -15,13 +18,31 @@ import jakarta.validation.constraints.NotNull; @SuppressWarnings("unused") public interface ReadLockSimple extends ReadLock { + /** + * 使用读锁执行指定回调 + *

+ * {@link #lock(LockType, tryRunnable, Consumer, Runnable)}指定读锁的变种 + */ + default + void read(@NotNull tryRunnable run, @Nullable Consumer catchby, @Nullable Runnable finaby) + { lock(LockType.READ, run, catchby, finaby); } + + /** + * 使用读锁执行指定回调 + *

+ * {@link #lock(LockType, tryRunnable, Runnable)}指定读锁的变种 + */ + default + void read(@NotNull tryRunnable run, @Nullable Runnable finaby) throws E + { lock(LockType.READ, run, finaby); } + /** * 使用读锁执行指定回调 *

* {@link #lock(LockType, trySupplier)}指定读锁的变种 */ default - R read(@NotNull trySupplier run) throws Exception + R read(@NotNull trySupplier run) throws E { return lock(LockType.READ, run); } /** @@ -30,6 +51,6 @@ interface ReadLockSimple extends ReadLock { * {@link #lock(LockType, tryRunnable)}指定读锁的变种 */ default - void read(@NotNull tryRunnable run) throws Exception + void read(@NotNull tryRunnable run) throws E { lock(LockType.READ, run); } } diff --git a/src/main/java/fybug/nulll/pdconcurrent/i/simple/TryLockSimple.java b/src/main/java/fybug/nulll/pdconcurrent/i/simple/TryLockSimple.java index 8e8976a9ebeeb6629fa9304703166a2ffaec369d..0e1e5235af495d095a7452c8d9911b12b87e82fa 100644 --- a/src/main/java/fybug/nulll/pdconcurrent/i/simple/TryLockSimple.java +++ b/src/main/java/fybug/nulll/pdconcurrent/i/simple/TryLockSimple.java @@ -1,10 +1,12 @@ package fybug.nulll.pdconcurrent.i.simple; +import java.util.function.Consumer; import java.util.function.Function; import fybug.nulll.pdconcurrent.e.LockType; -import fybug.nulll.pdconcurrent.fun.tryConsumer; -import fybug.nulll.pdconcurrent.fun.tryFunction; import fybug.nulll.pdconcurrent.i.TryLock; +import fybug.nulll.pdutilfunctionexpand.tryConsumer; +import fybug.nulll.pdutilfunctionexpand.tryFunction; +import jakarta.annotation.Nullable; import jakarta.validation.constraints.NotNull; /** @@ -16,13 +18,52 @@ import jakarta.validation.constraints.NotNull; */ public interface TryLockSimple extends TryLock { + /** + * 尝试使用锁执行指定回调 + *

+ * {@link #trylock(LockType, tryFunction, Function, Function)}的无返回变体 + */ + default + void trylock(@NotNull LockType lockType, @NotNull tryConsumer run, + @Nullable Consumer catchby, @Nullable Runnable finaby) + { + trylock(lockType, b -> { + run.accept(b); + return null; + }, catchby == null ? null : (E e) -> { + catchby.accept(e); + return null; + }, finaby == null ? null : _ -> { + finaby.run(); + return null; + }); + } + + /** + * 尝试使用锁执行指定回调 + *

+ * {@link #trylock(LockType, tryFunction, Function)}的无返回变体 + */ + default + void trylock(@NotNull LockType lockType, @NotNull tryConsumer run, + @Nullable Runnable finaby) throws E + { + trylock(lockType, b -> { + run.accept(b); + return null; + }, finaby == null ? null : _ -> { + finaby.run(); + return null; + }); + } + /** * 尝试使用锁执行指定回调 *

* {@link #trylock(LockType, tryFunction, Function)}的简易变体 */ default - R trylock(@NotNull LockType lockType, @NotNull tryFunction run) throws Exception + R trylock(@NotNull LockType lockType, @NotNull tryFunction run) throws E { return trylock(lockType, run, null); } /** @@ -31,6 +72,6 @@ interface TryLockSimple extends TryLock { * {@link #trylock(LockType, tryConsumer, Runnable)}的简易变体 */ default - void trylock(@NotNull LockType lockType, @NotNull tryConsumer run) throws Exception + void trylock(@NotNull LockType lockType, @NotNull tryConsumer run) throws E { trylock(lockType, run, null); } } diff --git a/src/main/java/fybug/nulll/pdconcurrent/i/simple/TryReadLockSimple.java b/src/main/java/fybug/nulll/pdconcurrent/i/simple/TryReadLockSimple.java index fd495f2bf1fa2a618c1d736c246d04f32ba0ea0a..1ff942e1aca8b732451663b14763e7d9cbe18ab7 100644 --- a/src/main/java/fybug/nulll/pdconcurrent/i/simple/TryReadLockSimple.java +++ b/src/main/java/fybug/nulll/pdconcurrent/i/simple/TryReadLockSimple.java @@ -1,8 +1,11 @@ package fybug.nulll.pdconcurrent.i.simple; +import java.util.function.Consumer; + import fybug.nulll.pdconcurrent.e.LockType; -import fybug.nulll.pdconcurrent.fun.tryConsumer; -import fybug.nulll.pdconcurrent.fun.tryFunction; import fybug.nulll.pdconcurrent.i.TryReadLock; +import fybug.nulll.pdutilfunctionexpand.tryConsumer; +import fybug.nulll.pdutilfunctionexpand.tryFunction; +import jakarta.annotation.Nullable; import jakarta.validation.constraints.NotNull; /** @@ -15,13 +18,32 @@ import jakarta.validation.constraints.NotNull; @SuppressWarnings("unused") public interface TryReadLockSimple extends TryReadLock { + /** + * 尝试使用读锁执行指定回调 + *

+ * {@link #trylock(LockType, tryConsumer, Consumer, Runnable)}指定读锁的变种 + */ + default + void tryread(@NotNull tryConsumer run, @Nullable Consumer catchby, + @Nullable Runnable finaby) + { trylock(LockType.READ, run, catchby, finaby); } + + /** + * 尝试使用读锁执行指定回调 + *

+ * {@link #trylock(LockType, tryConsumer, Runnable)}指定读锁的变种 + */ + default + void tryread(@NotNull tryConsumer run, @Nullable Runnable finaby) throws E + { trylock(LockType.READ, run, finaby); } + /** * 尝试使用读锁执行指定回调 *

* {@link #trylock(LockType, tryFunction)}指定读锁的变种 */ default - R tryread(@NotNull tryFunction run) throws Exception + R tryread(@NotNull tryFunction run) throws E { return trylock(LockType.READ, run); } /** @@ -30,6 +52,6 @@ interface TryReadLockSimple extends TryReadLock { * {@link #trylock(LockType, tryConsumer)}指定读锁的变种 */ default - void tryread(@NotNull tryConsumer run) throws Exception + void tryread(@NotNull tryConsumer run) throws E { trylock(LockType.READ, run); } } diff --git a/src/main/java/fybug/nulll/pdconcurrent/i/simple/TryWriteLockSimple.java b/src/main/java/fybug/nulll/pdconcurrent/i/simple/TryWriteLockSimple.java index 914693614fd62c2d0e9ba185fbbcd05f1e224ff8..085f5ae150112ddcb53ed33dfd198e801c41a1f0 100644 --- a/src/main/java/fybug/nulll/pdconcurrent/i/simple/TryWriteLockSimple.java +++ b/src/main/java/fybug/nulll/pdconcurrent/i/simple/TryWriteLockSimple.java @@ -1,8 +1,11 @@ package fybug.nulll.pdconcurrent.i.simple; +import java.util.function.Consumer; + import fybug.nulll.pdconcurrent.e.LockType; -import fybug.nulll.pdconcurrent.fun.tryConsumer; -import fybug.nulll.pdconcurrent.fun.tryFunction; import fybug.nulll.pdconcurrent.i.TryWriteLock; +import fybug.nulll.pdutilfunctionexpand.tryConsumer; +import fybug.nulll.pdutilfunctionexpand.tryFunction; +import jakarta.annotation.Nullable; import jakarta.validation.constraints.NotNull; /** @@ -15,13 +18,32 @@ import jakarta.validation.constraints.NotNull; @SuppressWarnings("unused") public interface TryWriteLockSimple extends TryWriteLock { + /** + * 尝试使用写锁执行指定回调 + *

+ * {@link #trylock(LockType, tryConsumer, Consumer, Runnable)}指定写锁的变种 + */ + default + void trywrite(@NotNull tryConsumer run, @Nullable Consumer catchby, + @Nullable Runnable finaby) + { trylock(LockType.WRITE, run, catchby, finaby); } + + /** + * 尝试使用写锁执行指定回调 + *

+ * {@link #trylock(LockType, tryConsumer, Runnable)}指定写锁的变种 + */ + default + void trywrite(@NotNull tryConsumer run, @Nullable Runnable finaby) throws E + { trylock(LockType.WRITE, run, finaby); } + /** * 尝试使用写锁执行指定回调 *

* {@link #trylock(LockType, tryFunction)}指定写锁的变种 */ default - R trywrite(@NotNull tryFunction run) throws Exception + R trywrite(@NotNull tryFunction run) throws E { return trylock(LockType.WRITE, run); } /** @@ -30,6 +52,6 @@ interface TryWriteLockSimple extends TryWriteLock { * {@link #trylock(LockType, tryConsumer)}指定写锁的变种 */ default - void trywrite(@NotNull tryConsumer run) throws Exception + void trywrite(@NotNull tryConsumer run) throws E { trylock(LockType.WRITE, run); } } diff --git a/src/main/java/fybug/nulll/pdconcurrent/i/simple/WriteLockSimple.java b/src/main/java/fybug/nulll/pdconcurrent/i/simple/WriteLockSimple.java index fbaa870f5537458c169d11d247009d4fae7c55de..14770d2b9b3843268594580d79e325939b135557 100644 --- a/src/main/java/fybug/nulll/pdconcurrent/i/simple/WriteLockSimple.java +++ b/src/main/java/fybug/nulll/pdconcurrent/i/simple/WriteLockSimple.java @@ -1,8 +1,11 @@ package fybug.nulll.pdconcurrent.i.simple; +import java.util.function.Consumer; + import fybug.nulll.pdconcurrent.e.LockType; -import fybug.nulll.pdconcurrent.fun.tryRunnable; -import fybug.nulll.pdconcurrent.fun.trySupplier; import fybug.nulll.pdconcurrent.i.WriteLock; +import fybug.nulll.pdutilfunctionexpand.tryRunnable; +import fybug.nulll.pdutilfunctionexpand.trySupplier; +import jakarta.annotation.Nullable; import jakarta.validation.constraints.NotNull; /** @@ -15,13 +18,31 @@ import jakarta.validation.constraints.NotNull; @SuppressWarnings("unused") public interface WriteLockSimple extends WriteLock { + /** + * 使用写锁执行指定回调 + *

+ * {@link #lock(LockType, tryRunnable, Consumer, Runnable)}指定写锁的变种 + */ + default + void write(@NotNull tryRunnable run, @Nullable Consumer catchby, @Nullable Runnable finaby) + { lock(LockType.WRITE, run, catchby, finaby); } + + /** + * 使用写锁执行指定回调 + *

+ * {@link #lock(LockType, tryRunnable, Runnable)}指定写锁的变种 + */ + default + void write(@NotNull tryRunnable run, @Nullable Runnable finaby) throws E + { lock(LockType.WRITE, run, finaby); } + /** * 使用写锁执行指定回调 *

* {@link #lock(LockType, trySupplier)}指定写锁的变种 */ default - R write(@NotNull trySupplier run) throws Exception + R write(@NotNull trySupplier run) throws E { return lock(LockType.WRITE, run); } /** @@ -30,6 +51,6 @@ interface WriteLockSimple extends WriteLock { * {@link #lock(LockType, tryRunnable)}指定写锁的变种 */ default - void write(@NotNull tryRunnable run) throws Exception + void write(@NotNull tryRunnable run) throws E { lock(LockType.WRITE, run); } } diff --git a/src/main/java/fybug/nulll/pdconcurrent/i/simple/package-info.java b/src/main/java/fybug/nulll/pdconcurrent/i/simple/package-info.java index 9b0b93ad4af265099b33ecb2420c63383e108b69..8a2cd51e9bc8d301f1b4bc175fa1c3589590856a 100644 --- a/src/main/java/fybug/nulll/pdconcurrent/i/simple/package-info.java +++ b/src/main/java/fybug/nulll/pdconcurrent/i/simple/package-info.java @@ -4,6 +4,6 @@ * * @author fybug * @version 0.0.1 - * @since PDConcurrent 0.1.3 + * @since i 0.0.2 */ package fybug.nulll.pdconcurrent.i.simple; \ No newline at end of file diff --git a/src/main/java/fybug/nulll/pdconcurrent/lock/ObjLock.java b/src/main/java/fybug/nulll/pdconcurrent/lock/ObjLock.java index 250ec5b75d0d565d1c7cf036552746daf10be054..6cf8caee6258fb0392e41b741c2c300fd8de6f6a 100644 --- a/src/main/java/fybug/nulll/pdconcurrent/lock/ObjLock.java +++ b/src/main/java/fybug/nulll/pdconcurrent/lock/ObjLock.java @@ -1,17 +1,17 @@ package fybug.nulll.pdconcurrent.lock; import java.util.function.Function; -import fybug.nulll.pdconcurrent.SyLock; import fybug.nulll.pdconcurrent.e.LockType; -import fybug.nulll.pdconcurrent.fun.tryFunction; -import fybug.nulll.pdconcurrent.fun.trySupplier; +import fybug.nulll.pdconcurrent.i.AbstractSyLock; +import fybug.nulll.pdutilfunctionexpand.tryFunction; +import fybug.nulll.pdutilfunctionexpand.trySupplier; import jakarta.annotation.Nullable; import jakarta.validation.constraints.NotNull; -import lombok.Getter; /** *

使用传统并发管理的实现.

- * 使用{@code synchronized( Object )}实现并发域,读写锁均为同一个实现 + * 使用{@code synchronized( Object )}实现并发域,读写锁均为同一个实现
+ * 因此也无法使用尝试上锁,其结果始终为{@code true} *

* 使用并发管理: * {@snippet lang = java: @@ -29,16 +29,13 @@ import lombok.Getter; * }} * * @author fybug - * @version 0.1.2 + * @version 0.1.3 + * @see AbstractSyLock * @since lock 0.0.1 */ @SuppressWarnings("unused") -@Getter public -class ObjLock implements SyLock { - /** 作为锁的对象 */ - private final Object LOCK; - +class ObjLock extends AbstractSyLock { /** * 构建并发管理 *

@@ -55,7 +52,7 @@ class ObjLock implements SyLock { * @since 0.1.0 */ public - ObjLock(@NotNull Object lock) { LOCK = lock; } + ObjLock(@NotNull Object lock) { super(new LockThreadContext<>(lock, false, null)); } /** * {@inheritDoc} @@ -65,91 +62,55 @@ class ObjLock implements SyLock { * @param catchby {@inheritDoc} * @param finaby {@inheritDoc} * @param {@inheritDoc} + * @param {@inheritDoc} * * @return {@inheritDoc} * - * @implNote 使用 {@code synchronized( Object )} 实现的隐式并发域 - * @since 0.1.0 + * @throws E1 {@inheritDoc} + * @implNote 使用java自带的synchronized进行上锁,因此无需进行二层异常捕获与解锁 + * @since ObjLock 0.1.3 */ - @Override + @SuppressWarnings("unchecked") public - R lock(@NotNull LockType lockType, @NotNull trySupplier run, @Nullable Function catchby, - @Nullable Function finaby) + R lockimpl(@NotNull LockType lockType, @NotNull trySupplier run, + @Nullable tryFunction catchby, + @Nullable Function finaby) throws E1 { R o = null; - // 不上锁 - if ( lockType == LockType.NOLOCK ) { - try { - // 主要内容 - o = run.get(); - } catch ( Exception e ) { - // 异常处理 - if ( catchby != null ) - o = catchby.apply(e); - } finally { - // 收尾 - if ( finaby != null ) - o = finaby.apply(o); - } - } else { - // 上锁 - synchronized ( LOCK ){ + try { + // 不上锁 + if ( lockType == LockType.NOLOCK ) { try { // 主要内容 o = run.get(); - } catch ( Exception e ) { + } catch ( Throwable e ) { // 异常处理 if ( catchby != null ) - o = catchby.apply(e); + o = catchby.apply((E) e); } finally { // 收尾 if ( finaby != null ) o = finaby.apply(o); } - } - } - return o; - } - - /** - * {@inheritDoc} - * - * @param lockType {@inheritDoc} - * @param run {@inheritDoc} - * @param finaby {@inheritDoc} - * @param {@inheritDoc} - * - * @return {@inheritDoc} - * - * @implNote 使用 {@code synchronized( Object )} 实现的隐式并发域 - * @since 0.1.2 - */ - @Override - public - R lock(@NotNull LockType lockType, @NotNull trySupplier run, @Nullable Function finaby) throws Exception { - R o = null; - // 不上锁 - if ( lockType == LockType.NOLOCK ) { - try { - // 主要内容 - o = run.get(); - } finally { - // 收尾 - if ( finaby != null ) - o = finaby.apply(o); - } - } else { - // 上锁 - synchronized ( LOCK ){ - try { - // 主要内容 - o = run.get(); - } finally { - // 收尾 - if ( finaby != null ) - o = finaby.apply(o); + } else { + // 上锁 + synchronized ( getLockThreadContext().getLock() ){ + try { + // 主要内容 + o = run.get(); + } catch ( Throwable e ) { + // 异常处理 + if ( catchby != null ) + o = catchby.apply((E) e); + } finally { + // 收尾 + if ( finaby != null ) + o = finaby.apply(o); + } } } + } finally { + removeLockThreadContext(); } return o; } @@ -162,33 +123,19 @@ class ObjLock implements SyLock { * @param catchby {@inheritDoc} * @param finaby {@inheritDoc} * @param {@inheritDoc} + * @param {@inheritDoc} * * @return {@inheritDoc} * - * @since 0.1.2 + * @throws E1 {@inheritDoc} + * @implNote 无法尝试上锁,直接使用{@link #lockimpl(LockType, trySupplier, tryFunction, Function)}实现 + * @since ObjLock 0.1.3 */ @Override - public - R trylock(@NotNull LockType lockType, @NotNull tryFunction run, @Nullable Function catchby, - @Nullable Function finaby) - { return lock(lockType, () -> run.apply(true), catchby, finaby); } - - /** - * {@inheritDoc} - * - * @param lockType {@inheritDoc} - * @param run {@inheritDoc} - * @param finaby {@inheritDoc} - * @param {@inheritDoc} - * - * @return {@inheritDoc} - * - * @throws Exception {@inheritDoc} - * @since 0.1.2 - */ - @Override - public - R trylock(@NotNull LockType lockType, @NotNull tryFunction run, @Nullable Function finaby) - throws Exception - { return lock(lockType, () -> run.apply(true), finaby); } + protected + R trylockimpl(@NotNull LockType lockType, + @NotNull tryFunction run, + @Nullable tryFunction catchby, + @Nullable Function finaby) throws E1 + { return lockimpl(lockType, () -> run.apply(true), catchby, finaby); } } diff --git a/src/main/java/fybug/nulll/pdconcurrent/lock/RWLock.java b/src/main/java/fybug/nulll/pdconcurrent/lock/RWLock.java index 4845fad60ecad33f42598af791d411c4577a9803..8ddae39fc843df6b8519dd22c5a3579e56b61d68 100644 --- a/src/main/java/fybug/nulll/pdconcurrent/lock/RWLock.java +++ b/src/main/java/fybug/nulll/pdconcurrent/lock/RWLock.java @@ -1,18 +1,18 @@ package fybug.nulll.pdconcurrent.lock; import java.util.LinkedList; +import java.util.WeakHashMap; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantReadWriteLock; import fybug.nulll.pdconcurrent.e.LockType; -import fybug.nulll.pdconcurrent.i.AbstractSyLock; +import fybug.nulll.pdconcurrent.i.AbstractRWSyLock; import jakarta.validation.constraints.NotNull; -import lombok.Getter; +import lombok.SneakyThrows; /** *

使用{@link ReentrantReadWriteLock}实现的并发管理.

* 使用{@link ReentrantReadWriteLock}实现并发域,读写锁均为标准实现,支持通过{@link #toread()}进行锁降级
- * 使用可中断的上锁操作{@link ReentrantReadWriteLock.ReadLock#lockInterruptibly()}和{@link ReentrantReadWriteLock.WriteLock#lockInterruptibly()}实现上锁
* 支持使用{@link #newReadCondition()}{@link #newWriteCondition()}获取{@link Condition} *

* 使用并发管理: @@ -46,22 +46,15 @@ import lombok.Getter; * }} * * @author fybug - * @version 0.1.1 + * @version 0.1.2 * @see ReentrantReadWriteLock * @see ReentrantReadWriteLock.ReadLock * @see ReentrantReadWriteLock.WriteLock * @since lock 0.0.1 */ @SuppressWarnings("unused") -@Getter public -class RWLock extends AbstractSyLock { - /** 锁 */ - private final ReentrantReadWriteLock LOCK; - /** 读锁 */ - private final ReentrantReadWriteLock.ReadLock Read_LOCK; - /** 写锁 */ - private final ReentrantReadWriteLock.WriteLock Write_LOCK; +class RWLock extends AbstractRWSyLock { /** * 每个线程的锁状态记录 * @@ -73,13 +66,13 @@ class RWLock extends AbstractSyLock { * * @since 0.1.1 */ - private final AtomicLong READ_LOCK_COUNTER = new AtomicLong(); + private final WeakHashMap READ_LOCK_COUNTER = new WeakHashMap<>(); /** * 写锁计数 * * @since 0.1.1 */ - private final AtomicLong WRITE_LOCK_COUNTER = new AtomicLong(); + private final WeakHashMap WRITE_LOCK_COUNTER = new WeakHashMap<>(); /** * 构建并发管理 @@ -105,11 +98,7 @@ class RWLock extends AbstractSyLock { * @since 0.1.0 */ public - RWLock(@NotNull ReentrantReadWriteLock lock) { - LOCK = lock; - Read_LOCK = LOCK.readLock(); - Write_LOCK = LOCK.writeLock(); - } + RWLock(@NotNull ReentrantReadWriteLock lock) { super(new LockThreadContext<>(lock, true, null)); } /** * 获取当前线程锁记录 @@ -131,35 +120,65 @@ class RWLock extends AbstractSyLock { return l; } + /** + * 获取当前线程读锁计数 + * + * @return 读锁计数对象 + * + * @since 0.1.2 + */ + @NotNull + private + AtomicLong getReadLockCounter(@NotNull ReentrantReadWriteLock lock) + { return READ_LOCK_COUNTER.computeIfAbsent(lock, k -> new AtomicLong()); } + + /** + * 获取当前线程写锁计数 + * + * @return 写锁计数对象 + * + * @since 0.1.2 + */ + @NotNull + private + AtomicLong getWriteLockCounter(@NotNull ReentrantReadWriteLock lock) + { return WRITE_LOCK_COUNTER.computeIfAbsent(lock, k -> new AtomicLong()); } + /** * {@inheritDoc} * * @param lockType {@inheritDoc} * - * @throws Exception {@inheritDoc} - * @implNote 使用 {@link ReentrantReadWriteLock} 实现的并发域,使用了{@code lockInterruptibly()}进行可中断的上锁操作
+ * @implNote 常规锁使用 {@code lock()}上锁,可中断锁使用{@code lockInterruptibly()}操作
* 会记录本次锁类型并记录读写锁的计数 * @since 0.1.1 */ + @SneakyThrows @Override protected - void lock(@NotNull LockType lockType) throws InterruptedException { - // 获取记录列表 - var l = getCurrentThreadLockState(); + void lock(@NotNull LockType lockType) { + var c = getLockThreadContext(); // 检查锁类型进行上锁,并更新对应锁计数 if ( lockType != LockType.NOLOCK ) { if ( lockType == LockType.READ ) { - Read_LOCK.lockInterruptibly(); - READ_LOCK_COUNTER.getAndIncrement(); + // 上锁 + if ( c.isInterruptiblyLock() ) + c.getLock().readLock().lockInterruptibly(); + else + c.getLock().readLock().lock(); + getReadLockCounter(c.getLock()).getAndIncrement(); } else if ( lockType == LockType.WRITE ) { - Write_LOCK.lockInterruptibly(); - WRITE_LOCK_COUNTER.getAndIncrement(); + // 上锁 + if ( c.isInterruptiblyLock() ) + c.getLock().writeLock().lockInterruptibly(); + else + c.getLock().writeLock().lock(); + getWriteLockCounter(c.getLock()).getAndIncrement(); } // 记录本次锁类型 - l.add(lockType); - } else if ( l.isEmpty() ) { + getCurrentThreadLockState().add(lockType); + } else if ( getCurrentThreadLockState().isEmpty() ) LOCK_STATE.remove(); - } } /** @@ -169,38 +188,45 @@ class RWLock extends AbstractSyLock { * * @return {@inheritDoc} * - * @implNote 使用 {@link ReentrantReadWriteLock} 实现的并发域,使用了{@code trylock()}实现
- * 会记录本次锁类型并记录读写锁的计数 + * @implNote 使用 {@code trylock()} 实现,会记录本次锁类型并记录读写锁的计数 * @since 0.1.1 */ + @SuppressWarnings("ConstantValue") + @SneakyThrows @Override protected boolean trylock(@NotNull LockType lockType) { - // 获取记录列表 - var l = getCurrentThreadLockState(); // 是否成功 boolean success = false; + var c = getLockThreadContext(); + var t = c.getTryTimeout(); // 检查锁类型并上锁 if ( lockType != LockType.NOLOCK ) { - if ( lockType == LockType.READ ) - success = Read_LOCK.tryLock(); - else if ( lockType == LockType.WRITE ) - success = Write_LOCK.tryLock(); + if ( lockType == LockType.READ ) { + if ( t == null ) + success = c.getLock().readLock().tryLock(); + else + success = c.getLock().readLock().tryLock(t.getTimeout(), t.getUnit()); + } else if ( lockType == LockType.WRITE ) { + if ( t == null ) + success = c.getLock().writeLock().tryLock(); + else + success = c.getLock().writeLock().tryLock(t.getTimeout(), t.getUnit()); + } } + // 是否成功 if ( success ) { - // 记录本次锁类型 - l.add(lockType); // 更新对应锁计数 if ( lockType == LockType.READ ) - READ_LOCK_COUNTER.getAndIncrement(); - else // noinspection ConstantValue - if ( lockType == LockType.WRITE ) - WRITE_LOCK_COUNTER.getAndIncrement(); - } else if ( l.isEmpty() ) { + getReadLockCounter(c.getLock()).getAndIncrement(); + else if ( lockType == LockType.WRITE ) + getWriteLockCounter(c.getLock()).getAndIncrement(); + // 记录本次锁类型 + getCurrentThreadLockState().add(lockType); + } else if ( getCurrentThreadLockState().isEmpty() ) LOCK_STATE.remove(); - } return success; } @@ -225,16 +251,16 @@ class RWLock extends AbstractSyLock { LOCK_STATE.remove(); return; } - + var c = getLockThreadContext(); // 获取最后锁类型 var lockType = l.removeLast(); // 检查锁类型解锁,并更新对应锁计数 if ( lockType == LockType.READ ) { - Read_LOCK.unlock(); - READ_LOCK_COUNTER.getAndDecrement(); + c.getLock().readLock().unlock(); + getReadLockCounter(c.getLock()).getAndDecrement(); } else if ( lockType == LockType.WRITE ) { - Write_LOCK.unlock(); - WRITE_LOCK_COUNTER.getAndDecrement(); + c.getLock().writeLock().unlock(); + getWriteLockCounter(c.getLock()).getAndDecrement(); } // 记录清空 @@ -255,6 +281,7 @@ class RWLock extends AbstractSyLock { boolean toread() { // 获取记录列表 var l = getCurrentThreadLockState(); + var c = getLockThreadContext(); // 没有上锁 if ( l.isEmpty() ) { LOCK_STATE.remove(); @@ -268,22 +295,23 @@ class RWLock extends AbstractSyLock { return true; else if ( lockType == LockType.WRITE ) { // 锁降级 - Read_LOCK.lock(); - Write_LOCK.unlock(); + c.getLock().readLock().lock(); + c.getLock().writeLock().unlock(); // 更新记录 - l.set(l.size() - 1, LockType.WRITE); + l.set(l.size() - 1, LockType.READ); // 更新计数 - WRITE_LOCK_COUNTER.getAndDecrement(); - READ_LOCK_COUNTER.getAndIncrement(); + getWriteLockCounter(c.getLock()).getAndDecrement(); + getReadLockCounter(c.getLock()).getAndIncrement(); return true; } return false; } /** - * 检查锁是否被占用 + * /** + * {@inheritDoc} * - * @return 是否被占用 + * @return {@inheritDoc} * * @since 0.1.0 */ @@ -299,7 +327,7 @@ class RWLock extends AbstractSyLock { * @since 0.1.0 */ public - boolean isReadLocked() { return isWriteLocked() || READ_LOCK_COUNTER.get() > 0; } + boolean isReadLocked() { return isWriteLocked() || getReadLockCounter(getLockThreadContext().getLock()).get() > 0; } /** * 检查写锁是否被占用 @@ -309,12 +337,13 @@ class RWLock extends AbstractSyLock { * @since 0.1.0 */ public - boolean isWriteLocked() { return WRITE_LOCK_COUNTER.get() > 0; } + boolean isWriteLocked() { return getWriteLockCounter(getLockThreadContext().getLock()).get() > 0; } /** - * 检查当前线程是否持有锁 + * /** + * {@inheritDoc} * - * @return 当前线程是否拥有锁 + * @return {@inheritDoc} * * @since 0.1.1 */ @@ -330,20 +359,7 @@ class RWLock extends AbstractSyLock { * @since 0.1.1 */ public - boolean isReadLockedCurrentThread() { - // 获取锁队列 - var l = LOCK_STATE.get(); - // 没有记录 - if ( l == null ) - return false; - // 没有上锁 - if ( l.isEmpty() ) { - LOCK_STATE.remove(); - return false; - } - // 检查是否占用读锁 - return l.contains(LockType.WRITE) || l.contains(LockType.READ); - } + boolean isReadLockedCurrentThread() { return checkIsLockedCurrentThread(LOCK_STATE.get(), LockType.READ); } /** * 检查当前线程是否持有写锁 @@ -353,9 +369,18 @@ class RWLock extends AbstractSyLock { * @since 0.1.1 */ public - boolean isWriteLockedCurrentThread() { - // 获取锁队列 - var l = LOCK_STATE.get(); + boolean isWriteLockedCurrentThread() { return checkIsLockedCurrentThread(LOCK_STATE.get(), LockType.WRITE); } + + /** + * 检查是否有对应的锁在当前线程持有 + * + * @param l 锁记录 + * @param lockType 要检查的锁类型,包含其中一个则返回true + * + * @since 0.1.2 + */ + private + boolean checkIsLockedCurrentThread(@NotNull LinkedList l, @NotNull LockType... lockType) { // 没有记录 if ( l == null ) return false; @@ -364,8 +389,10 @@ class RWLock extends AbstractSyLock { LOCK_STATE.remove(); return false; } - // 检查是否占用读锁 - return l.contains(LockType.WRITE); + for ( var t : lockType ) + if ( l.contains(t) ) + return true; + return false; } /** @@ -378,7 +405,7 @@ class RWLock extends AbstractSyLock { */ @NotNull public - Condition newReadCondition() { return Read_LOCK.newCondition(); } + Condition newReadCondition() { return getLockThreadContext().getLock().readLock().newCondition(); } /** * 获取写锁{@link Condition} @@ -390,5 +417,5 @@ class RWLock extends AbstractSyLock { */ @NotNull public - Condition newWriteCondition() { return Write_LOCK.newCondition(); } + Condition newWriteCondition() { return getLockThreadContext().getLock().writeLock().newCondition(); } } \ No newline at end of file diff --git a/src/main/java/fybug/nulll/pdconcurrent/lock/ReLock.java b/src/main/java/fybug/nulll/pdconcurrent/lock/ReLock.java index 3defce9ff02909fc9ea19a16f8e005a97bd2bd73..4cfc5fe0c510a5b94cc50d13c653b3ee8a2ff135 100644 --- a/src/main/java/fybug/nulll/pdconcurrent/lock/ReLock.java +++ b/src/main/java/fybug/nulll/pdconcurrent/lock/ReLock.java @@ -1,16 +1,16 @@ package fybug.nulll.pdconcurrent.lock; +import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; import fybug.nulll.pdconcurrent.e.LockType; -import fybug.nulll.pdconcurrent.i.AbstractSyLock; +import fybug.nulll.pdconcurrent.i.AbstractRWSyLock; import jakarta.validation.constraints.NotNull; -import lombok.Getter; +import lombok.SneakyThrows; /** *

使用{@link ReentrantLock}实现的并发管理.

* 使用{@link ReentrantLock}实现并发域,读写锁均为同一个实现
- * 使用了可中断的上锁操作{@link ReentrantLock#lockInterruptibly()}实现
* 支持使用{@link #newCondition()}获取{@link Condition} *

* 使用并发管理: @@ -34,17 +34,13 @@ import lombok.Getter; * }} * * @author fybug - * @version 0.1.1 + * @version 0.1.3 * @see ReentrantLock * @since lock 0.0.1 */ @SuppressWarnings("unused") -@Getter public -class ReLock extends AbstractSyLock { - /** 锁 */ - private final ReentrantLock LOCK; - +class ReLock extends AbstractRWSyLock { /** * 构建并发管理 *

@@ -69,22 +65,27 @@ class ReLock extends AbstractSyLock { * @since 0.1.0 */ public - ReLock(@NotNull ReentrantLock LOCK) { this.LOCK = LOCK; } + ReLock(@NotNull ReentrantLock LOCK) { super(new LockThreadContext<>(LOCK, true, null)); } /** * {@inheritDoc} * * @param lockType {@inheritDoc} * - * @throws InterruptedException 所在线程被中断 - * @implNote 使用 {@link ReentrantLock} 实现的并发域,使用了{@link ReentrantLock#lockInterruptibly()}进行可中断的上锁操作 + * @implNote 常规锁使用 {@link ReentrantLock#lock()},可中断锁使用{@link ReentrantLock#lockInterruptibly()}实现 * @since 0.1.1 */ + @SneakyThrows @Override protected - void lock(@NotNull LockType lockType) throws InterruptedException { - if ( lockType != LockType.NOLOCK ) - LOCK.lockInterruptibly(); + void lock(@NotNull LockType lockType) { + var c = getLockThreadContext(); + if ( lockType != LockType.NOLOCK ) { + if ( c.isInterruptiblyLock() ) + c.getLock().lockInterruptibly(); + else + c.getLock().lock(); + } } /** @@ -94,14 +95,21 @@ class ReLock extends AbstractSyLock { * * @return {@inheritDoc} * - * @implNote 使用 {@link ReentrantLock} 实现的并发域,使用了{@link ReentrantLock#tryLock()}实现 + * @implNote 无参数时使用 {@link ReentrantLock#tryLock()} 实现,设置了超时时间时使用{@link ReentrantLock#tryLock(long, TimeUnit)} * @since 0.1.1 */ + @SneakyThrows @Override protected boolean trylock(@NotNull LockType lockType) { - if ( lockType != LockType.NOLOCK ) - return LOCK.tryLock(); + var c = getLockThreadContext(); + var t = c.getTryTimeout(); + if ( lockType != LockType.NOLOCK ) { + if ( t == null ) + return c.getLock().tryLock(); + else + return c.getLock().tryLock(t.getTimeout(), t.getUnit()); + } return false; } @@ -114,8 +122,9 @@ class ReLock extends AbstractSyLock { @Override public void unlock() { - if ( LOCK.isHeldByCurrentThread() ) - LOCK.unlock(); + var lock = getLockThreadContext().getLock(); + if ( lock.isHeldByCurrentThread() ) + lock.unlock(); } /** @@ -127,7 +136,7 @@ class ReLock extends AbstractSyLock { */ @NotNull public - Condition newCondition() { return LOCK.newCondition(); } + Condition newCondition() { return getLockThreadContext().getLock().newCondition(); } /** * {@inheritDoc} @@ -136,7 +145,7 @@ class ReLock extends AbstractSyLock { */ @Override public - boolean isLocked() { return LOCK.isLocked(); } + boolean isLocked() { return getLockThreadContext().getLock().isLocked(); } /** * {@inheritDoc} @@ -147,5 +156,5 @@ class ReLock extends AbstractSyLock { */ @Override public - boolean isLockedCurrentThread() { return LOCK.isHeldByCurrentThread(); } + boolean isLockedCurrentThread() { return getLockThreadContext().getLock().isHeldByCurrentThread(); } } diff --git a/src/main/java/fybug/nulll/pdconcurrent/lock/package-info.java b/src/main/java/fybug/nulll/pdconcurrent/lock/package-info.java index e2f659b613543c9adfaa092f1f003f6ec0deebbd..dc5ff0883b84684a2caf120c592162f295e08644 100644 --- a/src/main/java/fybug/nulll/pdconcurrent/lock/package-info.java +++ b/src/main/java/fybug/nulll/pdconcurrent/lock/package-info.java @@ -1,5 +1,5 @@ /** - *

各种锁的实现包.

+ *

各种锁的实现.

* * @author fybug * @version 0.0.1 diff --git a/src/main/java/fybug/nulll/pdconcurrent/package-info.java b/src/main/java/fybug/nulll/pdconcurrent/package-info.java index 53f2a469ed36b9c03df91291bdff9d5e9a9b82fa..b60435babd80f3e085c4a371ef29361ec3cc3735 100644 --- a/src/main/java/fybug/nulll/pdconcurrent/package-info.java +++ b/src/main/java/fybug/nulll/pdconcurrent/package-info.java @@ -2,10 +2,9 @@ *

并发管理工具.

* 用于并发管理的工具,使用回调在并发域中执行代码。
* 根据实现的不同并发管理也不同,但都实现{@link fybug.nulll.pdconcurrent.SyLock}接口
- * 附带{@code try***}的功能接口包{@link fybug.nulll.pdconcurrent.fun},在java原有的功能接口的基础上允许抛出异常 * * @author fybug - * @version 0.1.3 + * @version 0.1.4 * @since JDK 23+ */ package fybug.nulll.pdconcurrent; \ No newline at end of file