关于并发操作引起的数据安全和性能问题简单做个总结:
安全问题:
考虑两个方面:数据库锁和java多线程处理
数据库锁:
悲观锁和乐观锁
悲观锁:update行锁,表锁。在修改数据库行的时候利用数据库自身的特性,不让其他事务去操作这张表的这些数据,待提交之后,再执行提交。
乐观锁:默认不会发生事务并发导致数据安全问题。在提交的时候去校验一下版本号(Hibernate可以通过配置控制)或者时间戳。
数据库隔离级别:
脏读 不可重复读幻读
读取未提交 Y Y Y
读取已提交 N Y Y
可重现的读取 N N Y
序列化 N N N
java多线程:
同步方法或者同步块:synchronized(实例/Class)。原子性,可见性,有序性。
轻量级锁:volatile。可见性和有序性。可以用在boolean或者一些读的场景。
java.lang.concurrent.Lock包。
读写锁:读锁,在读的时候不允许其他线程写操作,但允许读操作;写锁,在写的时候不允许其他线程读写操作。可用于缓存。
private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
private final Lock r = rwl.readLock();
private final Lock w = rwl.writeLock();
线程池:所线程并发,可以创建线程池。线程池的作用可以在创建线程和销毁线程上节约性能。
Java通过Executors提供四种线程池,分别为:
newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
集合类线程安全:
用ConcurrentHashMap代替HashMap:采用锁分段技术提高性性能。
ArrayList怎么保证线程安全:
1、synchronized
2、 List<Map<String,Object>> data=Collections.synchronizedList(new ArrayList<Map<String,Object>>());
3、一般情况下,因为性能问题不考虑用Vector代替ArrayList。在使用ArrayList注意下线程安全。