解决并发问题的文章很多,这里简单做一汇总:
一、关键字
1、Synchronized2、 volatile
volatile关键字用来对共享变量的访问进行同步,上一次写入操作的结果对下一次读取操作是肯定可见的。(在写入volatile变量值之后,CPU缓存中的内容会被写回内存;在读取volatile变量时,CPU缓存中的对应内容会被置为失效,重新从主存中进行读取),volatile不使用锁,性能优于synchronized关键词。
其实volatile还有线程安全问题,就是当多个线程对变量进行操作的时候还是可能会造成变量的值不准确性。 然而用这些类却解决了这个问题 。
用一个例子说明:
class MyDate
{
private int volatile x;
public void opera()
{
x++;
}
}
上面的类,当有多个线程同时执行opera的时候,虽然x已经用了volatile关键字同步,但是未能防止x的值出错,虽然出错的概率小
二、java.util.concurrent包
1、java.util.concurrent.locks
Lock接口的三个方法1)如果用lock(阻塞),那就跟synchronized一样的,获取了锁,就开门了,同一时刻 其他的门就死等,不能干其他事情
2) 如果用tryLock(非阻塞),如果锁在给定等待时间内没有被另一个线程保持,且当前线程未被中断,则获取该锁。如 果当前线程已经保持此锁,则将保持计数加 1,该方法将返回 true。 如果超出了指定的等待时间,则返回值为 false。
boolean result = smsLock.tryLock(timeout, TimeUnit.MILLISECONDS);
if(result){
业务逻辑
} else {
业务逻辑
}
3)lockInterruptibly
Lock接口的实现类 ReentrantLock
读音[,ri:'entrәnt]。一个可重入的互斥锁,它具有与使用 synchronized 方法和语句所访问的隐式监视器锁相同的一些基本行为和语义,但功能更强大。
Lock lock = new ReentrantLock();
lock.lock();
try {
// update object state
}
finally {
lock.unlock();
}
Lock接口的实现类 ReentrantReadWriteLock
出现的目的就是针对ReentrantLock独占带来的性能问题,比如对于一个类的属性,希望的效果是在读取它的时候能多线程同时读,在写它的时候不能读,在读它的时候不能写。这样如果只是单单在方法上面加synchronized关键字,它会使所有的线程互斥,不能说多个线程能同时读取对象的值,虽然自己编写代码实现,但是JAVA5之后线程并发库已经给了解决方案,那就是读写锁
2、java.util.concurrent.Executors类
1)创建固定大小的线程池ExecutorService service = Executors.newFixedThreadPool(3);//创建一个大小为3的线程池
2)创建可变大小线程池
ExecutorService service = Executors. newCachedThreadPool();
3) 创建一个定时器样式的线程池
ScheduledExecutorService service = Executors.newScheduledThreadPool(4);
4)创建单线程的线程池
ExecutorService service = Executors.newSingleThreadExecutor();
ExecutorService的方法
*提交任务的四个方法:
submit(Callable<T> task);
submit(Runnable task)
submit(Runnable task, T result)
execute()
说明:前三个方法都是带有返回值的执行任务,最后一个方法只是单纯的执行任务,方法的返回值是Future类型的,它是支持泛型的,返回值要和泛型的类型一致
Future<String> future = service.submit(new Callable<String>() {
Public String call() throws Exception() {
Return “test”;
}
});
//得到返回值
String str = future.get();
当使用submit(Runnable task)的时候,里面执行的是run方法是没有返回值的,
得到的future.get()得到的是Null值,表示线程正常执行完成
线程执行完毕关闭线程池里拥有的线程:
两个方法:
shutdown():调用的时候会先完成当前正在执行和已经提交的任务
shutdownNow():结束当前正在执行的任务和等待的任务也不会执行,返回待执行任务列表
3、java.util.concurrent.atomic类讲解
4、java.util.concurrent.同步集合类的讲解
ConcurrentHashMap
ConcurrentSkipListMap
ConcurrentSkipListSet
CopyOnWriteArrayList
CopyOnWriteArraySet
5、java.util.concurrent.队列的讲解
三、java.util.Collections类
静态方法有:synchronizedList
synchronizedSet
synchronizedMap
synchronizedSortedSet
synchronizedSortedMap