diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000000000000000000000000000000000000..8af972cded0d3e3ccb3c6e801150168bcc93150a
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,3 @@
+/gradlew text eol=lf
+*.bat text eol=crlf
+*.jar binary
diff --git a/.gitignore b/.gitignore
index 3ee9f36f53f97ee347cd95332ba4e5578c13215c..c2065bc26202b2d072aca3efc3d1c2efad3afcbf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,19 +1,37 @@
-pdfunctionlibrary.properties
-pdfunctionlibrary.xml
-# Ignore Gradle GUI config
-gradle-app.setting
+HELP.md
+.gradle
+build/
+!gradle/wrapper/gradle-wrapper.jar
+!**/src/main/**/build/
+!**/src/test/**/build/
-# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
-!gradle-wrapper.jar
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+bin/
+!**/src/main/**/bin/
+!**/src/test/**/bin/
-# Cache of project
-.gradletasknamecache
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+out/
+!**/src/main/**/out/
+!**/src/test/**/out/
-.gradle/
-.idea/
-build/
-gradlew.bat
-gradlew
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
-# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898
-# gradle/wrapper/gradle-wrapper.properties
+### VS Code ###
+.vscode/
diff --git a/README.md b/README.md
index 8660d33377a2d60d09b3367a7d60212012c6c984..d71eb39f1ee3f312e5b4ab5a7aba2077cde934e7 100644
--- a/README.md
+++ b/README.md
@@ -4,8 +4,8 @@
# PDConcurrent

-
-
+
+

-- [Java Doc](https://apidoc.gitee.com/fybug/PDConcurrent) --
@@ -28,16 +28,13 @@
### \> > 基础使用示例
```java
-// 尝试申请读锁
-SyLock.newObjLock().read(() -> {
+public static void main(String[] args) {
+ var lock = SyLock.newObjLock();
+ lock.read(() -> {
// 并发域代码内容
[return null;]? // 可选择是否返回
-});
-
-// 尝试申请写锁
-SyLock.newObjLock().write(() -> {
- [return null;]?
-});
+ });
+}
```
以上即为核心用法,将需要并发处理的代码通过一个 `Runnable` 接口包起来。启用并发管理以及停止并发管理部分的的代码由本工具封装,直接通过上述代码的方式传入需要运行的内容即可
@@ -50,48 +47,58 @@ SyLock.newObjLock().write(() -> {
### \> > synchronized 锁
```java
-// 使用
-SyLock.newObjLock().read(() -> {
+public static void main(String[] args) {
+ // 使用
+ var lock = SyLock.newObjLock();
+ lock.read(() -> {
// 并发域代码内容
-});
+ });
-// 不使用
-synchronized ( new Object() ){
+ // 不使用
+ synchronized ( new Object() ){
// 并发域代码内容
+ }
}
+
```
### \> > ReentrantLock 锁
```java
-// 使用
-SyLock.newReLock().read(() -> {
+public static void main(String[] args) {
+ // 使用
+ var lock = SyLock.newReLock();
+ lock.read(() -> {
// 并发域代码内容
-});
+ });
-// 不使用
-ReentrantLock lock = new ReentrantLock();
-try {
+ // 不使用
+ ReentrantLock lock = new ReentrantLock();
+ try {
lock.lock();
// 并发域代码内容
-} finally {
+ } finally {
lock.unlock();
+ }
}
```
### \> > ReadWriteLock 锁
```java
-// 使用
-SyLock.newRWLock().read(() -> {
+public static void main(String[] args) {
+ // 使用
+ var lock = SyLock.newRWLock();
+ lock.read(() -> {
// 并发域代码内容
-});
+ });
-// 不使用
-ReadWriteLock lock = new ReentrantReadWriteLock();
-try {
+ // 不使用
+ ReadWriteLock lock = new ReentrantReadWriteLock();
+ try {
lock.readLock().lock();
// 并发域代码内容
-} finally {
+ } finally {
lock.readLock().unlock();
+ }
}
```
@@ -100,8 +107,6 @@ try {
> PDConcurrent.jar 为不包含源码的包
>
-> PDConcurrent_all.jar 为包含了源码的包
->
> PDConcurrent_sources.jar 为仅包含源码的包
**发行版中可以看到全部版本
项目下的 jar 文件夹是当前最新的每夜版**
diff --git a/build.gradle b/build.gradle
index c0a688bde4e8a9bcf1a5ba7893e9cd6a64f72748..7fad4d0c2c7dd5b1d2699d64abd737d83a456e86 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,105 +1,125 @@
plugins {
- id 'java'
- id 'idea'
+ id 'java'
+ id 'idea'
}
-tasks.withType(JavaCompile) {
- options.encoding = "UTF-8"
+tasks.withType(JavaCompile).configureEach {
+ options.encoding = "UTF-8"
}
group 'fybug.nulll'
-version = '0.0.2'
-sourceCompatibility = '14'
-targetCompatibility = '14'
+version = '0.1.0'
-configurations {
- developmentOnly
- runtimeClasspath {
- extendsFrom developmentOnly
- }
- compileOnly {
- extendsFrom annotationProcessor
- }
+java {
+ toolchain {
+ languageVersion = JavaLanguageVersion.of(23)
+ }
}
repositories {
- mavenLocal()
- mavenCentral()
- maven { url 'https://repo.spring.io/milestone' }
- maven { url 'https://repo.spring.io/snapshot' }
- maven { url "https://maven.aliyun.com/repository/central" }
- maven { url "https://maven.aliyun.com/repository/public" }
- maven { url "https://maven.aliyun.com/repository/google" }
- maven { url "https://maven.aliyun.com/repository/gradle-plugin" }
- maven { url "https://maven.aliyun.com/repository/spring" }
- maven { url "https://maven.aliyun.com/repository/spring-plugin" }
- maven { url "https://maven.aliyun.com/repository/grails-core" }
- maven { url "https://maven.aliyun.com/repository/apache-snapshots" }
- maven { url "http://repo.spring.io/milestone" }
+ mavenLocal()
+ mavenCentral()
+ google()
+ maven { url 'https://maven.aliyun.com/repository/releases' }
+ maven { url "https://maven.aliyun.com/repository/jcenter" }
+ maven { url "https://maven.aliyun.com/repository/mapr-public" }
+ maven { url "https://maven.aliyun.com/repository/staging-alpha" }
+ maven { url "https://maven.aliyun.com/repository/central" }
+ maven { url "https://maven.aliyun.com/repository/public/" }
+ maven { url "https://maven.aliyun.com/repository/google" }
+ maven { url "https://maven.aliyun.com/repository/gradle-plugin" }
+ maven { url "https://maven.aliyun.com/repository/spring" }
+ maven { url "https://maven.aliyun.com/repository/spring-plugin" }
+ maven { url "https://maven.aliyun.com/repository/grails-core" }
+ maven { url "https://maven.aliyun.com/repository/snapshots" }
+ maven { url "https://maven.aliyun.com/repository/apache-snapshots" }
+ maven { url "https://maven.aliyun.com/repository/staging-alpha-group" }
}
dependencies {
- implementation fileTree(dir: 'lib', includes: ['*.jar'])
- compileOnly "org.jetbrains:annotations:17.0.0"
- compileOnly "org.projectlombok:lombok:1.18.10"
- annotationProcessor "org.projectlombok:lombok:1.18.10"
+ implementation fileTree(dir: 'lib', includes: ['*.jar'])
- testCompile "junit:junit:4.12"
- testCompileOnly "org.jetbrains:annotations:17.0.0"
- testCompileOnly "org.projectlombok:lombok:1.18.10"
+ compileOnly "jakarta.validation:jakarta.validation-api:+"
+ compileOnly "jakarta.annotation:jakarta.annotation-api:+"
+ compileOnly 'org.projectlombok:lombok:+'
+ annotationProcessor 'org.projectlombok:lombok:+'
+
+ // testImplementation "junit:junit"
+ testCompileOnly "jakarta.validation:jakarta.validation-api:+"
+ testCompileOnly "jakarta.annotation:jakarta.annotation-api:+"
+ testCompileOnly "org.projectlombok:lombok:+"
+ testAnnotationProcessor "org.projectlombok:lombok:+"
+}
+
+test {
+ useJUnitPlatform()
}
-task PDConcurrent(type: Jar) {
- destinationDirectory = file('jar')
- manifest {
- attributes(
- 'Manifest-Version': '1.0',
- 'Built-By': 'fybug/风雨bu改',
- 'Created-By': 'IntelliJ IDEA'
- )
- }
- archiveFileName = 'PDConcurrent.jar'
- // 打包编译输出
- from sourceSets.main.output
+task PDConcurrent_bin(type: Jar) {
+ destinationDirectory = file('jar')
+ manifest {
+ attributes('Manifest-Version': '1.0',
+ 'Built-By': 'fybug/风雨bu改',
+ 'Build-Jdk-Spec': 23,
+ 'Bundle-Description': 'java并发控制工具',
+ 'Bundle-Name': 'PDConcurrent',
+ 'Bundle-DocURL': 'https://apidoc.gitee.com/fybug/PDConcurrent/',
+ 'Bundle-Vendor': 'IntelliJ IDEA',
+ 'Bundle-Version': version,
+ 'Bundle-License': 'https://www.apache.org/licenses/LICENSE-2.0',
+ 'Created-By': 'Gradle 8.10.2')
+ }
+ archiveFileName = 'PDConcurrent_bin.jar'
+ // 打包编译输出
+ from sourceSets.main.output
}
task PDConcurrent_all(type: Jar) {
- destinationDirectory = file('jar')
- manifest {
- attributes(
- 'Manifest-Version': '1.0',
- 'Built-By': 'fybug/风雨bu改',
- 'Created-By': 'IntelliJ IDEA'
- )
- }
- archiveFileName = 'PDConcurrent_all.jar'
- // 打包编译输出
- from sourceSets.main.output
- // 打包源码
- from sourceSets.main.allSource
- from {
- // implementation 相关的引入解压并打包入新的jar中
- configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
- }
+ destinationDirectory = file('jar')
+ manifest {
+ attributes('Manifest-Version': '1.0',
+ 'Built-By': 'fybug/风雨bu改',
+ 'Build-Jdk-Spec': 23,
+ 'Bundle-Description': 'java并发控制工具',
+ 'Bundle-Name': 'PDConcurrent',
+ 'Bundle-DocURL': 'https://apidoc.gitee.com/fybug/PDConcurrent/',
+ 'Bundle-Vendor': 'IntelliJ IDEA',
+ 'Bundle-Version': version,
+ 'Bundle-License': 'https://www.apache.org/licenses/LICENSE-2.0',
+ 'Created-By': 'Gradle 8.10.2')
+ }
+ archiveFileName = 'PDConcurrent_all.jar'
+ // 打包编译输出
+ from sourceSets.main.output
+ // 打包源码
+ from sourceSets.main.allSource
+ from {
+ // implementation 相关的引入解压并打包入新的jar中
+ configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
+ }
}
task PDConcurrent_sources(type: Jar) {
- destinationDirectory = file('jar')
- manifest {
- attributes(
- 'Manifest-Version': '1.0',
- 'Built-By': 'fybug/风雨bu改',
- 'Created-By': 'IntelliJ IDEA'
- )
- }
- archiveFileName = 'PDConcurrent_sources.jar'
- // 打包源码
- from sourceSets.main.allSource
+ destinationDirectory = file('jar')
+ manifest {
+ attributes('Manifest-Version': '1.0',
+ 'Built-By': 'fybug/风雨bu改',
+ 'Build-Jdk-Spec': 23,
+ 'Bundle-Description': 'java并发控制工具',
+ 'Bundle-Name': 'PDConcurrent',
+ 'Bundle-DocURL': 'https://apidoc.gitee.com/fybug/PDConcurrent/',
+ 'Bundle-Vendor': 'IntelliJ IDEA',
+ 'Bundle-Version': version,
+ 'Bundle-License': 'https://www.apache.org/licenses/LICENSE-2.0',
+ 'Created-By': 'Gradle 8.10.2')
+ }
+ archiveFileName = 'PDConcurrent_sources.jar'
+ // 打包源码
+ from sourceSets.main.allSource
}
task release {
- dependsOn clean
- dependsOn PDConcurrent_all
- dependsOn PDConcurrent
- dependsOn PDConcurrent_sources
+ dependsOn clean
+ dependsOn PDConcurrent_bin
+ dependsOn PDConcurrent_sources
}
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000000000000000000000000000000000000..a4b76b9530d66f5e68d973ea569d8e19de379189
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 622ab64a3cb60378cd29384961554c0b032c9368..df97d72b8b91fa0e088ae27b1c84a6063481fe22 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
+networkTimeout=10000
+validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
new file mode 100644
index 0000000000000000000000000000000000000000..f5feea6d6b116baaca5a2642d4d9fa1f47d574a7
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,252 @@
+#!/bin/sh
+
+#
+# Copyright © 2015-2021 the original authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+
+##############################################################################
+#
+# Gradle start up script for POSIX generated by Gradle.
+#
+# Important for running:
+#
+# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+# noncompliant, but you have some other compliant shell such as ksh or
+# bash, then to run this script, type that shell name before the whole
+# command line, like:
+#
+# ksh Gradle
+#
+# Busybox and similar reduced shells will NOT work, because this script
+# requires all of these POSIX shell features:
+# * functions;
+# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+# * compound commands having a testable exit status, especially «case»;
+# * various built-in commands including «command», «set», and «ulimit».
+#
+# Important for patching:
+#
+# (2) This script targets any POSIX shell, so it avoids extensions provided
+# by Bash, Ksh, etc; in particular arrays are avoided.
+#
+# The "traditional" practice of packing multiple parameters into a
+# space-separated string is a well documented source of bugs and security
+# problems, so this is (mostly) avoided, by progressively accumulating
+# options in "$@", and eventually passing that to Java.
+#
+# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+# see the in-line comments for details.
+#
+# There are tweaks for specific operating systems such as AIX, CygWin,
+# Darwin, MinGW, and NonStop.
+#
+# (3) This script is generated from the Groovy template
+# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+# within the Gradle project.
+#
+# You can find Gradle at https://github.com/gradle/gradle/.
+#
+##############################################################################
+
+# Attempt to set APP_HOME
+
+# Resolve links: $0 may be a link
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+ APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
+ [ -h "$app_path" ]
+do
+ ls=$( ls -ld "$app_path" )
+ link=${ls#*' -> '}
+ case $link in #(
+ /*) app_path=$link ;; #(
+ *) app_path=$APP_HOME$link ;;
+ esac
+done
+
+# This is normally unused
+# shellcheck disable=SC2034
+APP_BASE_NAME=${0##*/}
+# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
+APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
+' "$PWD" ) || exit
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD=maximum
+
+warn () {
+ echo "$*"
+} >&2
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+} >&2
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "$( uname )" in #(
+ CYGWIN* ) cygwin=true ;; #(
+ Darwin* ) darwin=true ;; #(
+ MSYS* | MINGW* ) msys=true ;; #(
+ NONSTOP* ) nonstop=true ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD=$JAVA_HOME/jre/sh/java
+ else
+ JAVACMD=$JAVA_HOME/bin/java
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD=java
+ if ! command -v java >/dev/null 2>&1
+ then
+ die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+fi
+
+# Increase the maximum file descriptors if we can.
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+ case $MAX_FD in #(
+ max*)
+ # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
+ # shellcheck disable=SC2039,SC3045
+ MAX_FD=$( ulimit -H -n ) ||
+ warn "Could not query maximum file descriptor limit"
+ esac
+ case $MAX_FD in #(
+ '' | soft) :;; #(
+ *)
+ # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
+ # shellcheck disable=SC2039,SC3045
+ ulimit -n "$MAX_FD" ||
+ warn "Could not set maximum file descriptor limit to $MAX_FD"
+ esac
+fi
+
+# Collect all arguments for the java command, stacking in reverse order:
+# * args from the command line
+# * the main class name
+# * -classpath
+# * -D...appname settings
+# * --module-path (only if needed)
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if "$cygwin" || "$msys" ; then
+ APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+ CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+ JAVACMD=$( cygpath --unix "$JAVACMD" )
+
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ for arg do
+ if
+ case $arg in #(
+ -*) false ;; # don't mess with options #(
+ /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
+ [ -e "$t" ] ;; #(
+ *) false ;;
+ esac
+ then
+ arg=$( cygpath --path --ignore --mixed "$arg" )
+ fi
+ # Roll the args list around exactly as many times as the number of
+ # args, so each arg winds up back in the position where it started, but
+ # possibly modified.
+ #
+ # NB: a `for` loop captures its iteration list before it begins, so
+ # changing the positional parameters here affects neither the number of
+ # iterations, nor the values presented in `arg`.
+ shift # remove old arg
+ set -- "$@" "$arg" # push replacement arg
+ done
+fi
+
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Collect all arguments for the java command:
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
+# and any embedded shellness will be escaped.
+# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
+# treated as '${Hostname}' itself on the command line.
+
+set -- \
+ "-Dorg.gradle.appname=$APP_BASE_NAME" \
+ -classpath "$CLASSPATH" \
+ org.gradle.wrapper.GradleWrapperMain \
+ "$@"
+
+# Stop when "xargs" is not available.
+if ! command -v xargs >/dev/null 2>&1
+then
+ die "xargs is not available"
+fi
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+# set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+ printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+ xargs -n1 |
+ sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+ tr '\n' ' '
+ )" '"$@"'
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000000000000000000000000000000000000..27bf976f8e2ed20d0cc85746c8eabfc40d1765bd
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,94 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain DocumentType copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+@rem SPDX-License-Identifier: Apache-2.0
+@rem
+
+@if "%DEBUG%"=="" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%"=="" set DIRNAME=.
+@rem This is normally unused
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if %ERRORLEVEL% equ 0 goto execute
+
+echo. 1>&2
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
+echo. 1>&2
+echo Please set the JAVA_HOME variable in your environment to match the 1>&2
+echo location of your Java installation. 1>&2
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo. 1>&2
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
+echo. 1>&2
+echo Please set the JAVA_HOME variable in your environment to match the 1>&2
+echo location of your Java installation. 1>&2
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if %ERRORLEVEL% equ 0 goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+set EXIT_CODE=%ERRORLEVEL%
+if %EXIT_CODE% equ 0 set EXIT_CODE=1
+if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
+exit /b %EXIT_CODE%
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/jar/PDConcurrent.jar b/jar/PDConcurrent.jar
deleted file mode 100644
index 8ec6fad1d7a5d6088a2f411adaa0c4f4b28a6827..0000000000000000000000000000000000000000
Binary files a/jar/PDConcurrent.jar and /dev/null differ
diff --git a/jar/PDConcurrent_all.jar b/jar/PDConcurrent_all.jar
deleted file mode 100644
index ed9e7863610ec3b9360c8e6126ade0885b35b8db..0000000000000000000000000000000000000000
Binary files a/jar/PDConcurrent_all.jar and /dev/null differ
diff --git a/jar/PDConcurrent_bin.jar b/jar/PDConcurrent_bin.jar
new file mode 100644
index 0000000000000000000000000000000000000000..27dd86ee8081117386b9cd6d9a9f3c06e787a8ca
Binary files /dev/null and b/jar/PDConcurrent_bin.jar differ
diff --git a/jar/PDConcurrent_sources.jar b/jar/PDConcurrent_sources.jar
index bd9b5d8344b9bb4cf57a91fae0a48d0e4344be80..ea47ab642fe7fe7c73d815ec53d8dfee75682fae 100644
Binary files a/jar/PDConcurrent_sources.jar and b/jar/PDConcurrent_sources.jar differ
diff --git a/src/main/java/fybug/nulll/pdconcurrent/ObjLock.java b/src/main/java/fybug/nulll/pdconcurrent/ObjLock.java
index 4d5070d17f35a970fbb808ea66cc897521d21f82..d36d99e2036d341ddf59b6f388ebc4dda0b00e7e 100644
--- a/src/main/java/fybug/nulll/pdconcurrent/ObjLock.java
+++ b/src/main/java/fybug/nulll/pdconcurrent/ObjLock.java
@@ -1,81 +1,158 @@
package fybug.nulll.pdconcurrent;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.function.Supplier;
+import java.util.function.Function;
+import fybug.nulll.pdconcurrent.e.LockType;
import fybug.nulll.pdconcurrent.fun.trySupplier;
+import jakarta.annotation.Nullable;
+import jakarta.validation.constraints.NotNull;
import lombok.Getter;
/**
*
使用并发管理: - * public static - * void main(String[] args) { - * var lock = new ObjLock(); - * lock.read(() -> System.out.println("asd")); - * }- *
不使用: - * public static - * void main(String[] args) { - * synchronized ( new Object() ){ - * System.out.println("asd"); - * } - * }+ * 使用{@code synchronized( Object )}实现并发域,读写锁均为同一个实现 + *
+ * 使用一个新的{@link Object}
+ */
+ public
+ ObjLock() { this(new Object()); }
- //----------------------------------------------------------------------------------------------
+ /**
+ * 构建并发管理
+ *
+ * @param lock 用作锁的对象
+ *
+ * @since 0.1.0
+ */
+ public
+ ObjLock(@NotNull Object lock) { LOCK = lock; }
- @Override
- public
-
+ * 读锁为{@code 1}
+ * 使用非公平锁
+ */
+ public
+ RWLock() { this(false); }
+
+ /**
+ * 构造并发处理
+ *
+ * @param fair 是否使用公平锁
+ */
+ public
+ RWLock(boolean fair) { this(new ReentrantReadWriteLock(fair)); }
+
+ /**
+ * 构造并发处理
+ *
+ * @param lock 使用的锁
+ *
+ * @since 0.1.0
+ */
+ public
+ RWLock(@NotNull ReentrantReadWriteLock lock) {
+ LOCK = lock;
+ Read_LOCK = LOCK.readLock();
+ Write_LOCK = LOCK.writeLock();
+ }
+
+ //----------------------------------------------------------------------------------------------
+
+ /**
+ * {@inheritDoc}
+ *
+ * @param lockType {@inheritDoc}
+ * @param run {@inheritDoc}
+ * @param catchby {@inheritDoc}
+ * @param finaby {@inheritDoc}
+ * @param
+ * 使用了可中断的上锁操作{@link ReentrantReadWriteLock.ReadLock#lockInterruptibly()}和{@link ReentrantReadWriteLock.WriteLock#lockInterruptibly()}
+ * 根据{@link #LOCK_STATE}的状态调用对应的解锁动作
+ * 如果当前状态为写锁则会降级为读锁,否则不进行操作
+ *
+ * @return 是否成功降级
+ *
+ * @see #LOCK_STATE
+ * @since 0.1.0
+ */
+ public
+ boolean toread() {
+ // 转为读锁
+ if ( LOCK_STATE.get() == 2 ) {
+ Read_LOCK.lock();
+ Write_LOCK.unlock();
+ LOCK_STATE.set((short) 1);
+ return true;
+ }
+ return false;
+ }
+
+ //----------------------------------------------------------------------------------------------
+
+ /**
+ * 检查锁是否被占用
+ *
+ * @return 是否被占用
+ *
+ * @since 0.1.0
+ */
+ public
+ boolean isLocked() { return LOCK_STATE.get() != null && (LOCK_STATE.get() == 1 || LOCK_STATE.get() == 2); }
+
+ /**
+ * 检查读锁是否被占用
+ *
+ * @return 是否被占用
+ *
+ * @since 0.1.0
+ */
+ public
+ boolean isReadLocked() { return LOCK_STATE.get() == 1; }
+
+ /**
+ * 检查写锁是否被占用
+ *
+ * @return 是否被占用
+ *
+ * @since 0.1.0
+ */
+ public
+ boolean isWriteLocked() { return LOCK_STATE.get() == 2; }
+
+ /**
+ * 获取读锁{@link Condition}
+ *
+ * @see ReentrantReadWriteLock.ReadLock#newCondition()
+ * @since 0.1.0
+ */
+ @NotNull
+ public
+ Condition newReadCondition() { return Read_LOCK.newCondition(); }
- @Getter final private ReentrantReadWriteLock LOCK;
- @Getter final private ReentrantReadWriteLock.ReadLock Read_LOCK;
- @Getter final private ReentrantReadWriteLock.WriteLock Write_LOCK;
-
- public
- RWLock() {this(false);}
-
- /** 生成并发管理,并指定是否使用公平锁 */
- public
- RWLock(boolean fair) {
- LOCK = new ReentrantReadWriteLock(false);
- Read_LOCK = LOCK.readLock();
- Write_LOCK = LOCK.writeLock();
- }
-
- //----------------------------------------------------------------------------------------------
-
- @Override
- public
-
+ * 使用非公平锁
+ */
+ public
+ ReLock() { this(false); }
+
+ /**
+ * 构造并发处理
+ *
+ * @param fair 是否使用公平锁
+ */
+ public
+ ReLock(boolean fair) { this(new ReentrantLock(fair)); }
+
+ /**
+ * 构造并发处理
+ *
+ * @param LOCK 使用的锁
+ *
+ * @since 0.1.0
+ */
+ public
+ ReLock(@NotNull ReentrantLock LOCK) { this.LOCK = LOCK; }
+
+ //----------------------------------------------------------------------------------------------
+
+ /**
+ * {@inheritDoc}
+ *
+ * @param lockType {@inheritDoc}
+ * @param run {@inheritDoc}
+ * @param catchby {@inheritDoc}
+ * @param finaby {@inheritDoc}
+ * @param
+ * 可通过传入{@link LockType}指定锁的类型,运行时自带try-catch-finally块,通过三个回调参数插入不同的块中执行
+ * 可通过传入{@link LockType}指定锁的类型,运行时自带try-catch-finally块,通过三个回调参数插入不同的块中执行
+ * 可通过传入{@link LockType}指定锁的类型,运行时自带try-catch-finally块,遇到异常不处理返回{@code null}
+ *
+ * @param lockType 锁类型
+ * @param run 带返回的回调
+ * @param
+ * 可通过传入{@link LockType}指定锁的类型,运行时自带try-catch-finally块,遇到异常不处理
+ *
+ * @param lockType 锁类型
+ * @param run 执行的回调
+ *
+ * @see tryRunnable
+ * @see LockType
+ * @see #lock(LockType, trySupplier, Function, Function)
+ * @since 0.1.0
+ */
+ default
+ void lock(@NotNull LockType lockType, @NotNull tryRunnable run) {
+ lock(lockType, () -> {
+ run.run();
+ return null;
+ }, null, null);
+ }
- //------------------------------------
+ //-----------------------------------------------
- /**
- * 申请并运行于读锁
- *
- * @param run 带返回的运行代码
- *
- * @return 接口生成的数据
- */
-
+ * 可通过传入{@link LockType}指定锁的类型,运行时自带try-finally块,通过两个回调参数插入不同的块中执行,遇到异常会抛出
+ * 可通过传入{@link LockType}指定锁的类型,运行时自带try-finally块,通过两个回调参数插入不同的块中执行,遇到异常会抛出
+ * 可通过传入{@link LockType}指定锁的类型,运行时自带try-finally块,遇到异常会抛出
+ *
+ * @param lockType 锁类型
+ * @param run 带返回的回调
+ * @param
+ * 可通过传入{@link LockType}指定锁的类型,运行时自带try-finally块,遇到异常会抛出
+ *
+ * @param lockType 锁类型
+ * @param run 执行的回调
+ *
+ * @see tryRunnable
+ * @see LockType
+ * @see #trylock(LockType, trySupplier, Function)
+ * @since 0.1.0
+ */
+ default
+ void trylock(@NotNull LockType lockType, @NotNull tryRunnable run) throws Exception {
+ trylock(lockType, () -> {
+ run.run();
+ return null;
+ }, null);
+ }
- //------------------------------------
+ /*--------------------------------------------------------------------------------------------*/
- /**
- * 尝试运行于读锁
- *
- * @param ecla 异常的类
- * @param run 带返回的运行代码
- *
- * @return 接口生成的数据
- */
-
+ * 调用读锁执行,运行时自带try-catch-finally块,遇到异常不处理
+ *
+ * @param run 带返回的回调
+ * @param
+ * 调用读锁执行,运行时自带try-catch-finally块,遇到异常不处理
+ *
+ * @param run 执行的回调
+ *
+ * @see tryRunnable
+ * @see LockType#READ
+ * @see #lock(LockType, trySupplier, Function, Function)
+ * @since 0.1.0
+ */
+ default
+ void read(@NotNull tryRunnable run) {
+ lock(LockType.READ, () -> {
+ run.run();
+ return null;
+ }, null, null);
+ }
- //----------------------------------------------------------------------------------------------
+ /**
+ * 使用写锁执行指定回调
+ *
+ * 调用写锁执行,运行时自带try-catch-finally块,遇到异常不处理
+ *
+ * @param run 带返回的回调
+ * @param
+ * 调用写锁执行,运行时自带try-catch-finally块,遇到异常不处理
+ *
+ * @param run 执行的回调
+ *
+ * @see tryRunnable
+ * @see LockType#WRITE
+ * @see #lock(LockType, trySupplier, Function, Function)
+ * @since 0.1.0
+ */
+ default
+ void write(@NotNull tryRunnable run) {
+ lock(LockType.WRITE, () -> {
+ run.run();
+ return null;
+ }, null, null);
+ }
- /**
- * 尝试运行于写锁
- *
- * @param ecla 异常的类
- * @param run 运行代码
- * @param cate 异常处理代码
- *
- * @since SyLock 0.0.2
- */
- default
-
+ * 调用读锁执行,运行时自带try-catch-finally块,通过三个回调参数插入不同的块中执行
+ * 调用读锁执行,运行时自带try-catch-finally块,通过三个回调参数插入不同的块中执行
+ * 调用写锁执行,运行时自带try-catch-finally块,通过三个回调参数插入不同的块中执行
+ * 调用写锁执行,运行时自带try-catch-finally块,通过三个回调参数插入不同的块中执行
+ * 调用读锁执行,运行时自带try-finally块,遇到异常会抛出
+ *
+ * @param run 带返回的回调
+ * @param
+ * 调用读锁执行,运行时自带try-finally块,遇到异常会抛出
+ *
+ * @param run 执行的回调
+ *
+ * @see tryRunnable
+ * @see LockType#READ
+ * @see #trylock(LockType, trySupplier, Function)
+ * @since 0.1.0
+ */
+ default
+ void tryread(@NotNull tryRunnable run) throws Exception {
+ trylock(LockType.READ, () -> {
+ run.run();
+ return null;
+ }, null);
+ }
- /**
- * 尝试运行于读锁
- *
- * @param ecla 异常的类
- * @param run 带返回的运行代码
- * @param cate 异常处理代码
- * @param finall finally 块处理代码
- *
- * @return 接口生成的数据
- *
- * @since SyLock 0.0.2
- */
- default
-
+ * 调用写锁执行,运行时自带try-finally块,遇到异常会抛出
+ *
+ * @param run 带返回的回调
+ * @param
+ * 调用写锁执行,运行时自带try-finally块,遇到异常会抛出
+ *
+ * @param run 执行的回调
+ *
+ * @see tryRunnable
+ * @see LockType#WRITE
+ * @see #trylock(LockType, trySupplier, Function)
+ * @since 0.1.0
+ */
+ default
+ void trywrite(@NotNull tryRunnable run) throws Exception {
+ trylock(LockType.WRITE, () -> {
+ run.run();
+ return null;
+ }, null);
+ }
- /*--------------------------------------------------------------------------------------------*/
+ /*--------------------------------------------------------------------------------------------*/
- /** 获取传统并发实现 */
- static @NotNull
- ObjLock newObjLock() {return new ObjLock();}
+ /**
+ * 获取传统并发实现
+ *
+ * @see ObjLock
+ */
+ @NotNull
+ static
+ ObjLock newObjLock() { return new ObjLock(); }
- /** 获取 Lock 实现 */
- static @NotNull
- ReLock newReLock() {return new ReLock();}
+ /**
+ * 获取可重入锁实现
+ *
+ * @see ReLock
+ */
+ @NotNull
+ static
+ ReLock newReLock() { return new ReLock(); }
- /** 获取读写锁实现 */
- static @NotNull
- RWLock newRWLock() {return new RWLock();}
+ /**
+ * 获取读写锁实现
+ *
+ * @see RWLock
+ */
+ @NotNull
+ static
+ RWLock newRWLock() { return new RWLock(); }
}
diff --git a/src/main/java/fybug/nulll/pdconcurrent/e/LockType.java b/src/main/java/fybug/nulll/pdconcurrent/e/LockType.java
new file mode 100644
index 0000000000000000000000000000000000000000..0d722ea273db811863a73af8443091d55bac7a1b
--- /dev/null
+++ b/src/main/java/fybug/nulll/pdconcurrent/e/LockType.java
@@ -0,0 +1,18 @@
+package fybug.nulll.pdconcurrent.e;
+
+/**
+ * 使用并发管理:
- * public static
- * void main(String[] args) {
- * var lock = new RWLock();
- * lock.read(() -> System.out.println("adsa"));
- * lock.write(() -> System.out.println("adsa"));
- * }
- * 不使用:
- * public static
- * void main(String[] args) {
- * var lock = new ReentrantReadWriteLock();
- * lock.readLock().lock();
- * try {
- * System.out.println("adsa");
- * } finally {
- * lock.readLock().unlock();
- * }
- * lock.writeLock().lock();
- * try {
- * System.out.println("adsa");
- * } finally {
- * lock.writeLock().unlock();
- * }
- * }
+ * 使用{@link ReentrantReadWriteLock}实现的并发管理.
+ * 使用{@link ReentrantReadWriteLock}实现并发域,读写锁均为标准实现,支持通过{@link #toread()}进行锁降级
+ * 使用了可中断的上锁操作{@link ReentrantReadWriteLock.ReadLock#lockInterruptibly()}和{@link ReentrantReadWriteLock.WriteLock#lockInterruptibly()}
+ * 支持使用{@link #newReadCondition()}{@link #newWriteCondition()}获取{@link Condition},通过{@link #isLocked()}{@link #isWriteLocked()}{@link #isReadLocked()}检查是否被占用
+ *
+ * 使用并发管理:
+ * {@snippet lang = java:
+ * public static void main(String[] args) {
+ * var lock = new RWLock();
+ * // 使用读锁
+ * lock.read(() -> System.out.println("adsa"));
+ * // 使用写锁
+ * lock.write(() -> System.out.println("adsa"));
+ * }}
+ * 不使用:
+ * {@snippet lang = java:
+ * import java.util.concurrent.locks.ReentrantReadWriteLock;
+ * public static void main(String[] args) {
+ * var lock = new ReentrantReadWriteLock();
+ * // 使用读锁
+ * try {
+ * lock.readLock().lock();
+ * System.out.println("adsa");
+ * } finally {
+ * lock.readLock().unlock();
+ * }
+ * // 使用写锁
+ * try {
+ * lock.writeLock().lock();
+ * System.out.println("adsa");
+ * } finally {
+ * lock.writeLock().unlock();
+ * }
+ * }}
*
* @author fybug
- * @version 0.0.1
+ * @version 0.1.0
+ * @see SyLock
+ * @see LockType
+ * @see ReentrantReadWriteLock
+ * @see ReentrantReadWriteLock.ReadLock
+ * @see ReentrantReadWriteLock.WriteLock
* @since PDConcurrent 0.0.1
*/
+@Getter
public
class RWLock implements SyLock {
+ /** 锁 */
+ private final ReentrantReadWriteLock LOCK;
+ /** 读锁 */
+ private final ReentrantReadWriteLock.ReadLock Read_LOCK;
+ /** 写锁 */
+ private final ReentrantReadWriteLock.WriteLock Write_LOCK;
+ /**
+ * 每个线程的锁状态记录
+ *
+ * 写锁为{@code 2}
+ */
+ private final ThreadLocal
+ * 同时更新{@link #LOCK_STATE}记录
+ *
+ * @param lockType 锁类型
+ *
+ * @throws InterruptedException 上锁过程中被中断
+ * @see #LOCK_STATE
+ * @see LockType
+ * @since 0.1.0
+ */
+ private
+ void tolock(@NotNull LockType lockType) throws InterruptedException {
+ if ( lockType != LockType.NOLOCK ) {
+ if ( lockType == LockType.READ ) {
+ // 读锁
+ Read_LOCK.lockInterruptibly();
+ LOCK_STATE.set((short) 1);
+ } else {
+ // 写锁
+ Write_LOCK.lockInterruptibly();
+ LOCK_STATE.set((short) 2);
+ }
+ }
+ }
+
+ /**
+ * 根据状态解锁
+ *
+ * 成功后清空{@link #LOCK_STATE}内容
+ *
+ * @see #LOCK_STATE
+ * @since 0.1.0
+ */
+ private
+ void tounlock() {
+ // 根据实际状态解锁
+ if ( LOCK_STATE.get() == 1 )
+ Read_LOCK.unlock();
+ else if ( LOCK_STATE.get() == 2 )
+ Write_LOCK.unlock();
+ // 清除记录数据
+ LOCK_STATE.remove();
+ }
+
+ /**
+ * 转为读锁
+ * 使用并发管理:
- * public static
- * void main(String[] args) {
- * var lock = new ReLock();
- * lock.read(() -> System.out.println("asdas"));
- * }
- * 不使用:
- * public static
- * void main(String[] args) {
- * var lock = new ReentrantLock();
- * lock.lock();
- * try {
- * System.out.println("asdas");
- * } finally {
- * lock.unlock();
- * }
- * }
+ * 使用{@link ReentrantLock}实现的并发管理.
+ * 使用{@link ReentrantLock}实现并发域,读写锁均为同一个实现
+ * 使用了可中断的上锁操作{@link ReentrantLock#lockInterruptibly()}
+ * 支持使用{@link #newCondition()}获取{@link Condition},通过{@link #isLocked()}检查是否被占用
+ *
+ * 使用并发管理:
+ * {@snippet lang = java:
+ * public static void main(String[] args) {
+ * var lock = new ReLock();
+ * lock.read(() -> System.out.println("asdas"));
+ * }}
+ * 不使用:
+ * {@snippet lang = java:
+ * import java.util.concurrent.locks.ReentrantLock;
+ * public static void main(String[] args) {
+ * var lock = new ReentrantLock();
+ * lock.lock();
+ * try {
+ * System.out.println("asdas");
+ * } finally {
+ * lock.unlock();
+ * }
+ * }}
*
* @author fybug
- * @version 0.0.1
+ * @version 0.1.0
+ * @see SyLock
+ * @see ReentrantLock
* @since PDConcurrent 0.0.1
*/
+@Getter
public
class ReLock implements SyLock {
-
- // 锁
- @Getter private final ReentrantLock LOCK;
-
- public
- ReLock() {this(false);}
-
- /** 构造并发处理,并决定使用公平锁还是非公平锁 */
- public
- ReLock(boolean fair) { LOCK = new ReentrantLock(fair); }
-
- //----------------------------------------------------------------------------------------------
-
- @Override
- public
- 并发管理.
- * 通过使用接口运行的方式隐藏内部的并发管理方法
- * 让开发人员无需管理并发的具体方式
- * {@code **read()} 方法用于申请读取方法,{@code **write()} 用于申请写入方法,只有在使用读写锁实现 {@link RWLock} 才有区别。其余实现两个之间无区别
- * {@code try**()} 类型的方法为可抛出异常的方法,可在传入的接口中抛出异常,但是需要指定异常的类型
- * 也可在该类方法中传入 catch 块和 finally 块的代码,随后将不会抛出异常。发生异常后返回将会变为 {@code null}
+ * 通过传入回调的方式隐藏内部的并发管理方法,并支持复用内部的try块,通过传入的回调插入到catch,finally块中执行
+ * {@code **lock()} 方法用于根据传入的{@link LockType}申请不同的锁类型进行执行
+ * {@code **read()} 方法用于申请使用读锁,{@code **write()} 用于申请使用写锁,只有在使用读写锁实现 {@link RWLock} 才有区别。其余实现两个之间无区别
+ * {@code try**()} 类型的方法为可抛出异常的方法,可在传入的接口中抛出异常
*
* 使用 {@code new**Lock()} 的方法获取不同并发管理的实例
*
* @author fybug
- * @version 0.0.2
+ * @version 0.1.0
+ * @apiNote 并发控制通用接口,规定并实现大部分通用控制功能
* @since PDConcurrent 0.0.1
*/
public
interface SyLock {
+ /**
+ * 使用锁执行指定回调
+ *
+ * 所有回调均在并发域内执行
+ *
+ * @param lockType 锁类型
+ * @param run 带返回的回调
+ * @param catchby 进入catch块后的回调,传入当前异常
+ * @param finaby 进入finally块后的回调,传入前两个回调的返回值
+ * @param
+ * 任意一个回调为空时直接穿透,使用上一个正确执行的值进行传递或者返回,返回应有默认值{@code null}用于应对{@code catchby}和{@code finaby}都为空但是发生了异常的情况
+ * @see trySupplier
+ * @see Function
+ * @see LockType
+ * @since 0.1.0
+ */
+
+ * 所有回调均在并发域内执行
+ *
+ * @param lockType 锁类型
+ * @param run 执行的回调
+ * @param catchby 进入catch块后的回调,传入当前异常
+ * @param finaby 进入finally块后的回调
+ *
+ * @see tryRunnable
+ * @see Consumer
+ * @see Runnable
+ * @see LockType
+ * @see #lock(LockType, trySupplier, Function, Function)
+ * @since 0.1.0
+ */
+ default
+ void lock(@NotNull LockType lockType, @NotNull tryRunnable run, @Nullable Consumer
+ * 所有回调均在并发域内执行
+ *
+ * @param lockType 锁类型
+ * @param run 带返回的回调
+ * @param finaby 进入finally块后的回调,传入前一个回调的返回值,遇到异常传入{@code null}
+ * @param
+ * 任意一个回调为空时直接穿透,使用上一个正确执行的值进行传递或者返回,发生异常会执行{@code finaby}但是不会返回内容
+ * @see trySupplier
+ * @see Function
+ * @see LockType
+ * @since 0.1.0
+ */
+
+ * 所有回调均在并发域内执行
+ *
+ * @param lockType 锁类型
+ * @param run 执行的回调
+ * @param finaby 进入finally块后的回调
+ *
+ * @see tryRunnable
+ * @see Runnable
+ * @see LockType
+ * @see #trylock(LockType, trySupplier, Function)
+ * @since 0.1.0
+ */
+ default
+ void trylock(@NotNull LockType lockType, @NotNull tryRunnable run, @Nullable Runnable finaby) throws Exception {
+ trylock(lockType, () -> {
+ run.run();
+ return null;
+ }, finaby == null ? null : _ -> {
+ finaby.run();
+ return null;
+ });
+ }
- //----------------------------------------------------------------------------------------------
+ //-----------------------------------------------
- /**
- * 尝试运行于读锁
- *
- * @param ecla 异常的类
- * @param run 运行代码
- */
- default
-
+ * 所有回调均在并发域内执行
+ *
+ * @param run 带返回的回调
+ * @param catchby 进入catch块后的回调,传入当前异常
+ * @param finaby 进入finally块后的回调,传入前两个回调的返回值
+ * @param
+ * 所有回调均在并发域内执行
+ *
+ * @param run 执行的回调
+ * @param catchby 进入catch块后的回调,传入当前异常
+ * @param finaby 进入finally块后的回调
+ *
+ * @see tryRunnable
+ * @see Consumer
+ * @see Runnable
+ * @see LockType#READ
+ * @see #lock(LockType, trySupplier, Function, Function)
+ * @since 0.1.0
+ */
+ default
+ void read(@NotNull tryRunnable run, @Nullable Consumer
+ * 所有回调均在并发域内执行
+ *
+ * @param run 带返回的回调
+ * @param catchby 进入catch块后的回调,传入当前异常
+ * @param finaby 进入finally块后的回调,传入前两个回调的返回值
+ * @param
+ * 所有回调均在并发域内执行
+ *
+ * @param run 执行的回调
+ * @param catchby 进入catch块后的回调,传入当前异常
+ * @param finaby 进入finally块后的回调
+ *
+ * @see tryRunnable
+ * @see Consumer
+ * @see Runnable
+ * @see LockType#WRITE
+ * @see #lock(LockType, trySupplier, Function, Function)
+ * @since 0.1.0
+ */
+ default
+ void write(@NotNull tryRunnable run, @Nullable Consumer锁类型.
+ *
+ * @author fybug
+ * @version 0.0.1
+ * @since PDConcurrent 0.1.0
+ */
+public
+enum LockType {
+ /** 读锁 */
+ READ,
+ /** 写锁 */
+ WRITE,
+ /** 不上锁 */
+ NOLOCK
+}
diff --git a/src/main/java/fybug/nulll/pdconcurrent/fun/package-info.java b/src/main/java/fybug/nulll/pdconcurrent/fun/package-info.java
index 3034641e034c3d644552f82a4d71215b5d12983f..67680b723059e6f53ffc398616014843f534e497 100644
--- a/src/main/java/fybug/nulll/pdconcurrent/fun/package-info.java
+++ b/src/main/java/fybug/nulll/pdconcurrent/fun/package-info.java
@@ -2,7 +2,7 @@
* 功能接口包
*
* @author fybug
- * @version 0.0.2
+ * @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/tryBiConsumer.java b/src/main/java/fybug/nulll/pdconcurrent/fun/tryBiConsumer.java
deleted file mode 100644
index 291bc82d15370cbde79a4e75ec43f0621f75b4c7..0000000000000000000000000000000000000000
--- a/src/main/java/fybug/nulll/pdconcurrent/fun/tryBiConsumer.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package fybug.nulll.pdconcurrent.fun;
-import java.util.function.BiConsumer;
-
-/**
- * @author fybug
- * @version 0.0.1
- * @see BiConsumer
- * @since fun 0.0.1
- */
-@FunctionalInterface
-public
-interface tryBiConsumer并发管理工具.
- * 用于并发管理的工具,使用接口在并发域中执行代码。
- * 根据实现的不同并发管理也不同,但都实现 {@link fybug.nulll.pdconcurrent.SyLock} 接口
- * 附带 {@code try***} 的功能接口包,在 java 原有的功能接口的基础上允许抛出异常
+ * 用于并发管理的工具,使用回调在并发域中执行代码。
+ * 根据实现的不同并发管理也不同,但都实现{@link fybug.nulll.pdconcurrent.SyLock}接口
+ * 附带{@code try***}的功能接口包{@link fybug.nulll.pdconcurrent.fun},在java原有的功能接口的基础上允许抛出异常
*
* @author fybug
- * @version 0.0.1
- * @since JDK 13+
+ * @version 0.1.0
+ * @since JDK 23+
*/
package fybug.nulll.pdconcurrent;
\ No newline at end of file