多线程学习笔记-3
Atomic
使用锁可以保证原子性,但是带来会上下文切换和线程调度的开销,CAS(compare and swap)是jdk提供的非阻塞操作,通过硬件保证比较-更新的原子性
class A{
AtomicInteger v=new AtomicInteger();
int x;
}
public class Main{
public static void main(String[] args) throws InterruptedException {
int cnt=50000;
CountDownLatch countDownLatch=new CountDownLatch(cnt);
A a = new A();
for (int i = 0; i < cnt; i++) {
new Thread(()->{
a.x++;
a.v.incrementAndGet();
countDownLatch.countDown();
}).start();
}
countDownLatch.await();
System.out.println(a.v);
System.out.println(a.x);
}
}
volatile
保证内存可见性,不保证原子性,synchronized既保证原子性又保证可见性
什么时候用
- 更新变量时,不依赖变量当前值。如果依赖变量当前值,则修改有三步,读-计算-写入,也就是需要保证原子性,而volatile不能保证原子性
- 读写变量时,没有加锁。因为加锁本身保证内存可见性,没有必要声明为volatile
threadlocal
不同线程各自保存一个数据副本,每个线程只能访问修改自己的数据副本
class A{
String s;
void setV(String v){
this.s=v;
}
String getV(){
return s;
}
}
public class Main{
public static void main(String[] args) {
A a = new A();
for (int i = 0; i < 8; i++) {
new Thread(()->{
a.setV(Thread.currentThread().getName());
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(a.getV());
}).start();
}
}
}
class A{
ThreadLocal<String> s=new ThreadLocal<>();
}
public class Main{
public static void main(String[] args) {
A a = new A();
for (int i = 0; i < 8; i++) {
new Thread(()->{
a.s.set(Thread.currentThread().getName());
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(a.s.get());
}).start();
}
}
}
Semaphore
限制同时执行线程数量
public class Main{
public static void main(String[] args) {
Semaphore semaphore=new Semaphore(3);//最多3个线程一起执行,其他线程阻塞
for (int i = 0; i < 10; i++) {
new Thread(()->{
try {
semaphore.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"完成");
semaphore.release();
}).start();
}
}
}
CountDownLatch
等待若干个子任务线程都完成后,调用线程才继续往下执行
public class Main{
public static void main(String[] args) throws InterruptedException {
CountDownLatch countDownLatch=new CountDownLatch(3);
for (int i = 0; i < 3; i++) {
final int finalI=i;
new Thread(()->{
try {
TimeUnit.SECONDS.sleep(finalI);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"完成");
countDownLatch.countDown();
}).start();
}
countDownLatch.await();
System.out.println("全部完成");
}
}
CyclicBarrier
多个线程都到达一个屏障后,一同继续向下执行
public class Main{
public static void main(String[] args) {
CyclicBarrier cyclicBarrier=new CyclicBarrier(3,()->{
System.out.println("全部线程达到屏障");
});
for (int i = 0; i < 3; i++) {
final int I=i;
new Thread(()->{
try {
TimeUnit.SECONDS.sleep(I);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"到达屏障");
try {
cyclicBarrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"继续...");
}).start();
}
}
}

浙公网安备 33010602011771号