AtomicBoolean做什么,一个volatile布尔无法实现?
主题标题应该是自我探索的......我在下面的方法规范中有点困惑AtomicBoolean:
java.util.concurrent.atomic.AtomicBoolean#compareAndSetjava.util.concurrent.atomic.AtomicBoolean#getAndSet我的断言是,当在if条件中用作布尔子句时,两者都会产生相同的行为:
public class Test {
private AtomicBoolean flag = AtomicBoolean(false);
public void processSomeAction() {
if (flag.getAndSet(false)) { // Shouldn't this be similar to flag.compareAndSet(false)
// process some action
}
}
//...
private void internalMutatorMethod() {
// do some staff then update the atomic flag
flas.set(true);
}
}
Run Code Online (Sandbox Code Playgroud)
假设我想要检索当前标志值并自动更新它,两个方法是否应该产生相同的行为?
如果我错过内部差异,我将非常感谢有关如何以及何时使用这些解释的任何解释.
我试图通过替换一些synchronized块来减少代码中的线程争用AtomicBoolean.
这是一个例子synchronized:
public void toggleCondition() {
synchronized (this.mutex) {
if (this.toggled) {
return;
}
this.toggled = true;
// do other stuff
}
}
Run Code Online (Sandbox Code Playgroud)
替代方案AtomicBoolean:
public void toggleCondition() {
if (!this.condition.getAndSet(true)) {
// do other stuff
}
}
Run Code Online (Sandbox Code Playgroud)
利用AtomicBooleanCAS的属性应该比依赖同步更快,所以我运行了一些微基准测试.
对于10个并发线程和1000000次迭代,AtomicBoolean只比synchronized块快一点.
使用AtomicBoolean:0.0338在toggleCondition()上花费的平均时间(每个线程)
使用synchronized:0.0357在toggleCondition()上花费的平均时间(每个线程)
我知道微基准值得他们值得,但差异不应该更高吗?
我想在向外部系统发送请求时实施严格的循环调度.有两个外部系统服务器.第一个请求应该转到'System1',第二个请求必须转到'System2',然后转到'System1',依此类推.
因为我只有两个服务器来发送请求,并且因为我想要最大性能而没有任何阻塞和上下文切换,所以我已经使用了AtomicBoolean,因为它使用了CAS操作.
我的实现类
1. RoundRobinTest.java
package com.concurrency;
import java.util.Iterator;
public class RoundRobinTest
{
public static void main(String[] args)
{
for (int i = 0; i < 500; i++)
{
new Thread(new RoundRobinLogic()).start();
}
try
{
// Giving a few seconds for the threads to complete
Thread.currentThread().sleep(2000);
Iterator<String> output = RoundRobinLogic.output.iterator();
int i=0;
while (output.hasNext())
{
System.out.println(i+++":"+output.next());
// Sleeping after each out.print
Thread.currentThread().sleep(20);
}
}
catch (Exception ex)
{
// do nothing
}
}
}
Run Code Online (Sandbox Code Playgroud)
2.RoundRobinLogic.java(具有静态AtomicBoolean对象的类)
package com.concurrency;
import java.util.Queue; …Run Code Online (Sandbox Code Playgroud) 有人知道如何在 iOS 10 中创建原子布尔值吗?
当前代码:
import UIKit
struct AtomicBoolean {
fileprivate var val: UInt8 = 0
/// Sets the value, and returns the previous value.
/// The test/set is an atomic operation.
mutating func testAndSet(_ value: Bool) -> Bool {
if value {
return OSAtomicTestAndSet(0, &val)
} else {
return OSAtomicTestAndClear(0, &val)
}
}
/// Returns the current value of the boolean.
/// The value may change before this method returns.
func test() -> Bool {
return val != 0 …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用以下代码在 java 中的多线程应用程序中部署 TTAS:
AtomicBoolean state= new AtomicBoolean(false);
void lock(){
while(true)
{
while(state.get())
{
if(!state.getAndSet(true))
return;
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试旋转它的值时,我如何比较状态的值以检查它是真还是假,而每次遇到错误,说我正在尝试比较两个不同变量的类型?经验:
Lock lock = new Lock();
if(lock.state==true) // error !
{
//do something
}
Run Code Online (Sandbox Code Playgroud)
谢谢你!
我的代码包含一些AtomicBoolean字段.只调用这些字段的方法get()和set()方法.
这些字段的类型可以安全地用原始布尔值替换吗?
我的意思是,原始布尔值的赋值和访问操作是Java中的原子操作.从这个角度来看,我看不出有任何理由AtomicBoolean在我的案例中使用.
在我的理解中AtomicBoolean,只有compareAndSet使用的方法结合比较和访问才有意义.我错了吗?你能解释一下原因吗?
在我正在开发的应用程序中,我发现了以下代码片段:
public class MyClass {
private AtomicBoolean atomicBoolean = new AtomicBoolean(false);
public void Execute() {
// Whole lot of business logic
// ....
synchronized (this.atomicBoolean) {
// Want to make sure that execution is stopped if Stop() was called
if (this.atomicBoolean.get()) {
throw new SpecificException("...");
}
// Some more business logic...
}
}
public void Stop() {
synchronized (this.atomicBoolean) {
this.atomicBoolean.set(true);
}
}
}
Run Code Online (Sandbox Code Playgroud)
根据FindBugs的说法,这是不正确的,因为我不能与AtomicBoolean一起使用,synchronized并且不能期望它会阻塞对象。
我的问题是:重写此方法的正确方法是什么?我已经读过有关将锁对象与布尔属性一起使用的信息,但是为该锁引入两个新属性似乎有点笨拙。
编辑:正如下面的注释中所述:我认为目的是在两个synchronized块AtomicBoolean中不能更改,并且当一个线程位于其中一个synchronized块中时,不能再输入其他任何这样的块。
以下是Brian Goetz的Java Concurrency in Practice中列出7.20的代码:
public class CheckForMail {
public boolean checkMail(Set<String> hosts, long timeout, TimeUnit unit)
throws InterruptedException {
ExecutorService exec = Executors.newCachedThreadPool();
final AtomicBoolean hasNewMail = new AtomicBoolean(false);
try {
for (final String host : hosts)
exec.execute(new Runnable() {
public void run() {
if (checkMail(host)) hasNewMail.set(true);
}
});
} finally {
exec.shutdown();
exec.awaitTermination(timeout, unit);
}
return hasNewMail.get();
}
private boolean checkMail(String host) { // Check for mail return
false;
}
}
Run Code Online (Sandbox Code Playgroud)
参考此代码,Goetz说"使用AtomicBoolean而不是volatile布尔值的原因是为了从内部Runnable访问hasMail标志,它必须是final,这将阻止修改它"(p.158 ).
为什么它必须是最终的?难道你不能让它成为一个非最终的布尔波动?