Java高并发之无锁与Atomic源码分析(5)

public class AtomicIntegerFieldUpdaterDemo {
    public static class Candidate {
        int id;
        // 如果直接把int改成atomicinteger, 可能对代码破坏比较大
        // 因此使用AtomicIntegerFieldUpdater对score进行封装
        volatile int score;
    }

// 通过反射实现
    public final static AtomicIntegerFieldUpdater<Candidate> scoreUpdater = AtomicIntegerFieldUpdater.newUpdater(Candidate.class, "score");
    // 检查Updater是否工作正确, allScore的结果应该跟score一致
    public static AtomicInteger allScore = new AtomicInteger(0);

public static void main(String[] args) throws InterruptedException {
        final Candidate stu = new Candidate();
        Thread[] t = new Thread[10000];
        for (int i = 0; i < 10000; i++) {
            t[i] = new Thread() {
                public void run() {
                    if (Math.random() > 0.4) {
                        scoreUpdater.incrementAndGet(stu);
                        allScore.incrementAndGet();
                    }
                }
            };
            t[i].start();
        }
        for (int i = 0; i < 10000; i++) {
            t[i].join();
        }

System.out.println("score=" + stu.score);
        System.out.println("allScore=" + allScore);
    }
}

无锁的Vector

jdk中Vector是加锁的, 网上找的一个无锁Vector LockFreeVector, 给他添加了源码中文注释.

主要关注push_back, 添加元素的函数

import java.util.AbstractList;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.atomic.AtomicReferenceArray;

/**
 * It is a thread safe and lock-free vector.
 * This class implement algorithm from:<br>
 *
 * Lock-free Dynamically Resizable Arrays <br>
 *
 * @param <E> type of element in the vector
 *
 */
public class LockFreeVector<E> extends AbstractList<E> {
    private static final boolean debug = false;
    /**
    * Size of the first bucket. sizeof(bucket[i+1])=2*sizeof(bucket[i])
    */
    private static final int FIRST_BUCKET_SIZE = 8;

/**
    * number of buckets. 30 will allow 8*(2^30-1) elements
    */
    private static final int N_BUCKET = 30;

/**
    * We will have at most N_BUCKET number of buckets. And we have
    * sizeof(buckets.get(i))=FIRST_BUCKET_SIZE**(i+1)
    *
    * 为什么AtomicReferenceArray里再套一个AtomicReferenceArray呢, 类似一个篮子(buckets)里放了很多篮子
    * 为了在容量扩展时希望尽可能少的改动原有数据, 因此把一维数组扩展成二维数组.
    * 该二维数组并非均衡的分布. 可能第一个数组8个元素, 第二个数组16个元素, 第三个数组32个......
    */
    private final AtomicReferenceArray<AtomicReferenceArray<E>> buckets;

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/51b69d57160bd926d840d2e47e93aab2.html