java并发编程实践

java并发编程实践读书笔记

线程的粗粒度将会给性能带来极大影响

可见性

  • 在一个线程中也许无法确保能看到另一个线程写入的值,所以需要一定的同步机制

Volatile关键字

  • Java语言提供了一种稍弱的同步机制,即是volatile变量,当声明为volatile时,编译和运行时将会注意到该变量是共享的,不会被缓存到寄存器或其他处理器不可见的地方,因此每一次将会返回最新写入的值,比sychronized关键字更轻量化
  • volatile关键字只能确保其可见性
  • 当满足一下条件,才能使用volatile
    • 对变量的写入操作不依赖当前值,或者你能保证单个线程更新变量的值
    • 该变量不会与其他条件纳入不变性条件中
    • 在访问变量时不需要加锁

线程封闭

  • 不共享数据,仅在单线程里面访问数据,这就是线程封闭
  • Swing中大量使用了线程封闭,JDBC中通过connection的管理模式也实现了线程封闭

栈封闭

public int loadTheArk(Collection<Animal> candidates) {
        SortedSet<Animal> animals;
        int numPairs = 0;
        Animal candidate = null;

        // animals confined to method, don't let them escape!
        animals = new TreeSet<Animal>(new SpeciesGenderComparator());
        animals.addAll(candidates);
        for (Animal a : animals) {
            if (candidate == null || !candidate.isPotentialMate(a))
                candidate = a;
            else {
                ark.load(new AnimalPair(candidate, a));
                ++numPairs;
                candidate = null;
            }
        }
        return numPairs;
    }

ThreadLocal类

  • 这是个由JDK提供的一个类,更规范,能将某个值和保存值的对象连接起来,提供了set和get的访问接口或方法
public class ConnectionDispenser {
    static String DB_URL = "jdbc:mysql://localhost/mydatabase";

    private ThreadLocal<Connection> connectionHolder
            = new ThreadLocal<Connection>() {
                public Connection initialValue() {
                    try {
                        return DriverManager.getConnection(DB_URL);
                    } catch (SQLException e) {
                        throw new RuntimeException("Unable to acquire Connection, e");
                    }
                };
            };

    public Connection getConnection() {
        return connectionHolder.get();
    }
}

同步容器类

  • Vector和HashTable
  • 迭代器与ConcurrentModificationException(并发修改错误)
    • 可以加锁来避免发生错误
class BadListHelper <E> {
    public List<E> list = Collections.synchronizedList(new ArrayList<E>());

    public synchronized boolean putIfAbsent(E x) {
        boolean absent = !list.contains(x);
        if (absent)
            list.add(x);
        return absent;
    }
}
  • 隐藏迭代器(不要这么做,不要写如下代码)
public class HiddenIterator {
    @GuardedBy("this") private final Set<Integer> set = new HashSet<Integer>();

    public synchronized void add(Integer i) {
        set.add(i);
    }

    public synchronized void remove(Integer i) {
        set.remove(i);
    }

    public void addTenThings() {
        Random r = new Random();
        for (int i = 0; i < 10; i++)
            add(r.nextInt());
        System.out.println("DEBUG: added ten elements to " + set);
    }
}

并发容器

  • ConcurrentHashMap

Executor框架

  • 基于Executor框架的web服务器
  • 定长线程池,可以容纳100个线程
public class TaskExecutionWebServer {
    private static final int NTHREADS = 100;
    private static final Executor exec
            = Executors.newFixedThreadPool(NTHREADS);

    public static void main(String[] args) throws IOException {
        ServerSocket socket = new ServerSocket(80);
        while (true) {
            final Socket connection = socket.accept();
            Runnable task = new Runnable() {
                public void run() {
                    handleRequest(connection);
                }
            };
            exec.execute(task);
        }
    }

    private static void handleRequest(Socket connection) {
        // request-handling logic here
    }
}
  • Executor的不同线程池
    • newFixedThreadPool定长线程池
    • newCachedThreadPool创建可缓存线程池,当线程词超过处理需求时,将回收空闲线程,而当需求增加时,则可以添加新的线程
    • newSingleThreadExecutor是一个单线程的Executor
    • newScheduledThreadPool,创建一个固定长度的线程池,而且以延时或者定时的方式来执行任务

你可能感兴趣的:(并发,线程)