Java多线程 原子性操作类的使用
在并发编程中,多个线程同时进行操作时,可能会出现线程安全问题。例如两个线程同时对同一个变量进行增加操作,结果可能不是期望的那个。Java提供了原子性操作类来解决这个问题。
原子性操作类
Java原子类是Java编程语言中的一种特殊类,它具有原子性,线程安全性和可比性,并提供了一种简单的基于锁的技术,通过这种技术实现多线程并发访问时变量的安全。
AtomicInteger类的使用
AtomicInteger类提供了原子操作的int型变量,包括增加,减少,增加并赋值,减少并赋值,获取和设置等方法。
示例1
import java.util.concurrent.atomic.AtomicInteger;
public class AtomicIntegerExample {
private AtomicInteger count = new AtomicInteger(0);
public void increment() {
count.incrementAndGet();
}
public int getCount() {
return count.get();
}
public static void main(String[] args) throws InterruptedException {
AtomicIntegerExample example = new AtomicIntegerExample();
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10000; i++) {
example.increment();
}
}
});
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10000; i++) {
example.increment();
}
}
});
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.println(example.getCount());
}
}
示例2
import java.util.concurrent.atomic.AtomicInteger;
public class AtomicIntegerExample {
private AtomicInteger count = new AtomicInteger(0);
public void increment() {
count.addAndGet(10);
}
public int getCount() {
return count.get();
}
public static void main(String[] args) throws InterruptedException {
AtomicIntegerExample example = new AtomicIntegerExample();
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10000; i++) {
example.increment();
}
}
});
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10000; i++) {
example.increment();
}
}
});
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.println(example.getCount());
}
}
AtomicLong类、AtomicBoolean类和AtomicReference类的使用
除了AtomicInteger类外,Java还提供了AtomicLong类,AtomicBoolean类和AtomicReference类。这些类提供了相应的Java基础数据类型的原子操作。
示例3
import java.util.concurrent.atomic.AtomicLong;
public class AtomicLongExample {
private AtomicLong count = new AtomicLong(0);
public void increment() {
count.incrementAndGet();
}
public long getCount() {
return count.get();
}
public static void main(String[] args) throws InterruptedException {
AtomicLongExample example = new AtomicLongExample();
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10000; i++) {
example.increment();
}
}
});
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10000; i++) {
example.increment();
}
}
});
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.println(example.getCount());
}
}
示例4
import java.util.concurrent.atomic.AtomicBoolean;
public class AtomicBooleanExample {
private AtomicBoolean flag = new AtomicBoolean(false);
public void setFlag() {
flag.compareAndSet(false, true);
}
public boolean getFlag() {
return flag.get();
}
public static void main(String[] args) {
AtomicBooleanExample example = new AtomicBooleanExample();
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
example.setFlag();
}
});
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
while (!example.getFlag()) {
System.out.println("Flag not set yet.");
}
System.out.println("Flag is set.");
}
});
thread1.start();
thread2.start();
}
}
示例5
import java.util.concurrent.atomic.AtomicReference;
public class AtomicReferenceExample {
private AtomicReference<String> name = new AtomicReference<>("");
public void setName(String name) {
this.name.compareAndSet("", name);
}
public String getName() {
return name.get();
}
public static void main(String[] args) {
AtomicReferenceExample example = new AtomicReferenceExample();
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
example.setName("John");
}
});
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
while (example.getName().equals("")) {
System.out.println("Name not set yet.");
}
System.out.println("Name is " + example.getName() + ".");
}
});
thread1.start();
thread2.start();
}
}
总结
使用Java原子类可以有效地解决多线程并发访问时变量的安全问题。在使用时,应该根据需要选择不同的原子类。需要注意的是,原子操作虽然保证了操作的原子性,但并不一定保证线程安全,具体使用需要谨慎。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java多线程 原子性操作类的使用 - Python技术站