Skip to content

线程安全

yangyp8110 edited this page Jan 17, 2018 · 1 revision

ThreadLocal:线程局部变量,只有当前线程可以访问(线程安全)

  ThreadLocal 的set和get方法会先获取当前线程对象,然后在当前线程对象(ThreadLocalMap--弱引用)里存取数据。线程退出时,Thread会进行一些清理工作,包括清理ThreadLocalMap。在不用时,及时清理对象。

无锁线程安全类型(CAS -- 比较交换)

  • AtomicInteger(CAS保证线程安全)、AtomicLong、AtomicBoolean、AtomicReference、AtomicStampedReference(内部维护了一个时间戳) AtomicIntegerArray、AtomicLongArray、AtomicReferenceArray

不变模式:

  • a.去除setter方法以及所有能修改自身属性的方法
  • b.将所有属性设置为私有,并用final标记,确保其不可修改
  • c.确保没有子类可以重载修改它的行为
  • d.有一个可以创建完整对象的构造函数

不变模式主要应用场所:

  • a.当对象创建后,其内部状态和数据不再发生任何变化
  • b.对象需要被共享,被多线程频繁访问
    //不变模式
    public final class Product{//确保无子类
        private final String no;//私有属性,确保不会被其他对象获取
        private final String name;//final保证属性不会被再次赋值
        private final BigDecimal price;

        public Product(String no, String name, BigDecimal price) {
            this.no = no;
            this.name = name;
            this.price = price;
        }

        public String getNo() {
            return no;
        }

        public String getName() {
            return name;
        }

        public BigDecimal getPrice() {
            return price;
        }
    }

Disruptor(高效的无锁缓存队列)

Future模式

/**
 * Created by mr.yang on 2017/6/8.
 *
 * Callable接口是Future和应用之间通信的重要接口。
 *
 * 通常会使用Callable实例构造Future,然后提交给线程池,线程池Run方法内会调用callable的call实现方法
 */
public class test1Class {
    public class RealData implements Callable{
        private String para;

        public RealData(String para) {
            this.para = para;
        }

        @Override
        public Object call() throws Exception {
            StringBuffer sb =new StringBuffer();
            for (int i = 0; i < 10; i++) {
                sb.append(para);

                try {
                    Thread.sleep(200);
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
            }
            return sb.toString();
        }
    }

    public class FutureMain {
       public void test() throws ExecutionException, InterruptedException {
           FutureTask<String> future = new FutureTask<>(new RealData("AB"));
           ExecutorService executor = Executors.newFixedThreadPool(1);
           executor.submit(future);

           System.out.println(System.currentTimeMillis() +" : future请求完毕,继续执行");
           try {
               Thread.sleep(1000);
           } catch (InterruptedException ex) {
               ex.printStackTrace();
           }

           System.out.println(System.currentTimeMillis() +" : future读取数据中……");
           //同步读取(由输出时间可以得知:future.get是同步读取结果)
           String result = future.get();
           System.out.println(System.currentTimeMillis() +" : future返回:" + result);
       }
    }
}

Akka构建高并发

Clone this wiki locally