线程安全问题(迸发)入门知识总结

关于Java解决线程冲突的方法简单总结

1.在方法面前使用synchronized或者使用方法块
2.使用各种锁lock,Reentrantlock,读写锁
3.使用volatile保证可见性
4.使用ThreadLock复制变量副本
5.java.util.concurrent的API及StringBuffer

解决线程安全问题的各种方法的具体实现

A.Synchronized

synchronized的具体使用方法有两种
1.直接写在方法的修饰符或静态符后面
public synchronized void methodANeedSync(){//同步的代码}
2.在方法内使用synchronized块
public void methodANeedSync(){
 synchronized{
   //同步的代码
 }
}

B.锁

以Reentrantlock的使用为例
    在方法外实例化锁
    
class Demo
{
Lock lock=new Reentrantlock();
void methodANeedLock(){

lock.lock()
try{//需要锁的代码}
catch(Exception e){...}
finall{lock.unlock; //解锁 }
}
}
注意不能让锁变成方法的局部变量,因为每个线程都拥有一个局部变量的副本,会使得获取的锁不一样;

关于读写锁ReadWriteLock
具体实现 ReentrantReadWriteLock
与ReentrantLock的实现基本相同只是上锁和解锁的时候需要注明是读还是写的锁
如:
ReentrantReadWriteLock rrwl=new ReentrantReadWriteLock();
void methodANeedLock(){

rrwls.readlock.lock()
try{//需要锁的代码}
catch(Exception e){...}
finall{rrwl.readlock.jianlock; //解锁 }
}

C.volatile

此关键字修饰的的变量表示这个变量是易变的,不需要编译优化,一旦发生修改即可刷新到主内存中,保证变量的可见性

D.ThreadLocal

   可以理解为本地局部变量的意思,对于储存在里面的变量(最好是只有一个变量),使用ThreadLocal.get()方法访问储存在ThreadLocalMap的
   变量时,get()方法会判断当前时哪个线程然后基于一个变量副本,就像是一个在方法外部的局部变量一样;
 如使用ThreadLcocal实现线程安全的DAO层代码:
 public class ThreadLocalDAO {
  private static final ThreadLocal<Connection> conLocal=new ThreadLocal<Connection>();
  public Connection getCon(){
      Connection con=conLocal.get();
      if(con==null){
          try {
              Class.forName("com.mysql.jdbc.Driver");
              try {
                  con= DriverManager.getConnection("#url","#uesr","#password");
              } catch (SQLException e) {
                  e.printStackTrace();
              }
              conLocal.set(con);
          } catch (ClassNotFoundException e) {
              e.printStackTrace();
          }

      }
      return con;
  }

}


E.各种已经封装好且线程安全的集合类或其他API(多数在concurrent包内)

如常用的有:
a.实现BlockingQueue和DequeBlocking接口的所有类
{
ArrayBlockingQueue;
DelayQueue;
LinkedBlockingQueue;
PriorityBlockingQueue;
SynchronousQueue;
LinkedBlockingQueue;
}
b.所有以concurrent开头的集合类 如:concurrentHashMap
c.StringBuffer,Vector,Stack
d.concurrent包内的其他API

猜你喜欢

转载自blog.csdn.net/fengdaqin/article/details/83590566
今日推荐