在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
开源软件名称(OpenSource Name):Kotlin/kotlinx.atomicfu开源软件地址(OpenSource Url):https://github.com/Kotlin/kotlinx.atomicfu开源编程语言(OpenSource Language):Kotlin 99.8%开源软件介绍(OpenSource Introduction):AtomicFUThe idiomatic way to use atomic operations in Kotlin.
ExampleLet us declare a import kotlinx.atomicfu.* // import top-level functions from kotlinx.atomicfu
private val top = atomic<Node?>(null) Use fun isEmpty() = top.value == null // volatile read
fun clear() { top.value = null } // volatile write Use if (top.compareAndSet(expect, update)) ... Use higher-level looping primitives (inline extensions), for example: top.loop { cur -> // while(true) loop that volatile-reads current value
...
} Use high-level fun push(v: Value) = top.update { cur -> Node(v, cur) }
fun pop(): Value? = top.getAndUpdate { cur -> cur?.next } ?.value Declare atomic integers and longs using type inference: val myInt = atomic(0) // note: integer initial value
val myLong = atomic(0L) // note: long initial value Integer and long atomics provide all the usual Dos and Don'ts
private val _foo = atomic<T>(initial) // private atomic, convention is to name it with leading underscore
public var foo: T by _foo // public delegated property (val/var) Gradle build setupBuilding with Gradle is supported for all platforms. JVMYou will need Gradle 4.10 or later. Add and apply AtomicFU plugin. It adds all the corresponding dependencies and transformations automatically. See additional configuration if that needs tweaking. buildscript {
ext.atomicfu_version = '0.18.2'
dependencies {
classpath "org.jetbrains.kotlinx:atomicfu-gradle-plugin:$atomicfu_version"
}
}
apply plugin: 'kotlinx-atomicfu' JSConfigure add apply plugin just like for JVM. NativeThis library is available for Kotlin/Native ( Atomic references for Kotlin/Native are based on FreezableAtomicReference and every reference that is stored to the previously frozen (shared with another thread) atomic is automatically frozen, too. Since Kotlin/Native does not generally provide binary compatibility between versions,
you should use the same version of Kotlin compiler as was used to build AtomicFU.
See gradle.properties in AtomicFU project for its CommonIf you write a common code that should get compiled or different platforms, add dependencies {
compile "org.jetbrains.kotlinx:atomicfu:$atomicfu_version"
} IR transformation for Kotlin/JSThere is a new option to turn on IR transformation for Kotlin/JS backend.
You can add Here is how transformation is performed for different JS compiler modes with this option enabled:
Additional configurationTo set configuration options you should create atomicfu {
dependenciesVersion = '0.18.2'
} JVM transformation optionsTo turn off transformation for Kotlin/JVM set option Configuration option
JS transformation optionsTo turn off transformation for Kotlin/JS set option Here are all available configuration options (with their defaults): atomicfu {
dependenciesVersion = '0.18.2' // set to null to turn-off auto dependencies
transformJvm = true // set to false to turn off JVM transformation
jvmVariant = "FU" // JVM transformation variant: FU,VH, or BOTH
jsVariant = "JS" // JS transformation variant: JS or IR
verbose = false // set to true to be more verbose
} Maven build setupDeclare AtomicFU version: <properties>
<atomicfu.version>0.18.2</atomicfu.version>
</properties> Declare provided dependency on the AtomicFU library (the users of the resulting artifact will not have a dependency on AtomicFU library): <dependencies>
<dependency>
<groupId>org.jetbrains.kotlinx</groupId>
<artifactId>atomicfu</artifactId>
<version>${atomicfu.version}</version>
<scope>provided</scope>
</dependency>
</dependencies> Configure build steps so that Kotlin compiler puts classes into a different <build>
<plugins>
<!-- compile Kotlin files to staging directory -->
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${kotlin.version}</version>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<output>${project.build.directory}/classes-pre-atomicfu</output>
</configuration>
</execution>
</executions>
</plugin>
<!-- transform classes with AtomicFU plugin -->
<plugin>
<groupId>org.jetbrains.kotlinx</groupId>
<artifactId>atomicfu-maven-plugin</artifactId>
<version>${atomicfu.version}</version>
<executions>
<execution>
<goals>
<goal>transform</goal>
</goals>
<configuration>
<input>${project.build.directory}/classes-pre-atomicfu</input>
<!-- "VH" to use Java 9 VarHandle, "BOTH" to produce multi-version code -->
<variant>FU</variant>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build> Additional featuresAtomicFU provides some additional features that you can optionally use. Arrays of atomic valuesYou can declare arrays of all supported atomic value types.
By default arrays are transformed into the corresponding If you configure val a = atomicArrayOfNulls<T>(size) // similar to Array constructor
val x = a[i].value // read value
a[i].value = x // set value
a[i].compareAndSet(expect, update) // do atomic operations User-defined extensions on atomicsYou can define you own extension functions on @Suppress("NOTHING_TO_INLINE")
private inline fun AtomicBoolean.tryAcquire(): Boolean = compareAndSet(false, true) LocksThis project includes
Condition variables ( Testing lock-free data structures on JVMYou can optionally test lock-freedomness of lock-free data structures using
In order to make those test to actually perform lock-freedomness testing you need to configure an additional execution of tests with the original (non-transformed) classes for Maven: <build>
<plugins>
<!-- additional test execution with surefire on non-transformed files -->
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>lockfree-test</id>
<phase>test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<classesDirectory>${project.build.directory}/classes-pre-atomicfu</classesDirectory>
<includes>
<include>**/*LFTest.*</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build> For Gradle there is nothing else to add. Tests are always run using original (non-transformed) classes. Tracing operationsYou can debug your tests tracing atomic operations with a special trace object: private val trace = Trace()
private val current = atomic(0, trace)
fun update(x: Int): Int {
// custom trace message
trace { "calling update($x)" }
// automatic tracing of modification operations
return current.getAndAdd(x)
} All trace messages are stored in a cyclic array inside You can optionally set the size of trace's message array and format function. For example, you can add a current thread name to the traced messages: private val trace = Trace(size = 64) {
index, // index of a trace message
text // text passed when invoking trace { text }
-> "$index: [${Thread.currentThread().name}] $text"
}
|
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论