文档章节

线程同步

流光韶逝
 流光韶逝
发布于 2017/01/04 20:04
字数 1092
阅读 12
收藏 0

线程需要同步

意义

线程间同步,不仅保证变量执行的互斥,还保证变量的变化可以被其他线程捕获.

线程同步的方式:

  • Atomatic原子类 如AtomaticLong

  • volatile,修饰符. 用volatile修饰的变量,线程在每次使用变量的时候,都会读取变量修改后的最的值. 只保证读取的准确性;

  • synchronized; 锁,可以 用来修饰方法和代码块,保证同一时刻只有一个线程执行他们.

  • 其他的线程安全的容器或类, 如 CopyOnWriteList,CopyOnWriteSet,ConcurrentHashMap,ConcurrentLinkedDeque

总的来说,synchronized最安全,但费内存;一般而言,volatile和synchronized可以保证大多数的线程安全.

避免过度同步

  • 1.在同步区内做最少操作;这可以减少同发时间,提高性能

  • 2.将外来方法放在非同步区内;无法明确判断外来方法的执行时间

  • 3.尽量在类内部进行同步

exector和task优先于线程

  • 1.尽量不要只简单的使用 new Thread()之类的代码.用线程池可以方便线程的开启和关闭,唤醒执行等操作.

  • 2.尽量不要自己使用队列,使用专门的线程管理工具.队列无法控制线程的执行时间,无法有效的实现

java.util.concurrent工具包中有一个Executor框架,提供了三种线程池的创建方法.如Executors.newSingleExecutor(),Executors.newFixedTreadPool(n),Executors.newCachedTreadPool();有了它之后,就不需要自己创建队列去执行了.

  • Executors.newSingleExecutor() ;多余的线程会自动存储到线程池的队列里,等上一个线程执行完再执行.在核心资源紧张情况下使用.

  • Executors.newFixedTreadPool(n);并发次数为n,其他的线程池存储;可以根据cpu很好的调整并发的数量

  • Executors.newCachedTreadPool();有多少执行多少,适合并发教少的项目;

任务task,接口runnable和callable<T>;

  • runnable 无返回值

  • callable<T> 有返回值.

延迟初始化

一般而言,不需要延迟初始化,除非确定延迟初始化会是代码的性能得到提升.

静态域的延迟初始化

最好使用 lazy initialization holder class 模式.保证了类要被用到时才会被初始化.

//Lazy initialization holder class idiom for static fields
private  static class FieldHolder{
    static final FieldType field =computeFieldValue();
}

static FieldType getField(){
    return FieldHolder.field;
}

思路:用静态域的初始化来代替同步控制;这个流程不需要同步;

实例域初始化

双重检查模式(double-check idiom)

//double-ckeck idiom for lazy initialization of instance fields
private  volatile FieldType field;
FieldType getField(){
    FieldType result = field;
    if(result==null){
        synchronized(this){
            result=field;
            if(field==null){
                field=result=computeFieldValue();
            }
        }
    }
return result;
}

当实例域不接受重复初始化时,则选用此模式

单重检查模式(single-check idiom)

//Single-check idiom -can cause repeated initialization!

private volatile FieldType field;

private FieldType getField(){
    FieldType result=field;
    if(result==null){
        field=result=ComputeFieldValue();
    }
    return result;
}

这个模式下,实例域可能会被重复初始化.

双重检查模式和单重模式检查值为数值型是,应该为0;

并发工具

java.util.concurrent的高级工具类分为三种:Executor Framework,并发集合(Concurrent Collection),同步器(Synchronizer).这里介绍下同步器;

CountDown Latch 到计数锁存器

允许一个线程或多个线程等待其他线程处理别的事情.

static volatile int index = 0;

  public static Long time(Executor executor, int concurrency, final Runnable action) throws InterruptedException {
    final CountDownLatch ready = new CountDownLatch(concurrency);
    final CountDownLatch start = new CountDownLatch(1);
    final CountDownLatch done = new CountDownLatch(concurrency);
    for (int i = 0; i < concurrency; i++) {
      executor.execute(new Runnable() {

        @Override
        public void run() {
          ready.countDown();
          try {
            start.await();
            action.run();
          } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
          } finally {
            index++;
            done.countDown();
            System.out.println(index);
          }
        }

      });
    }
    ready.await();
    Long startNanos = System.nanoTime();
    start.countDown();
    done.await();
    return System.nanoTime() - startNanos;

  }

线程先准备,ready开始等待,接着计数解锁,可以执行其他线程;然后start等待,countDown解锁;最后done的await开始等待,然后执行完解锁.

不过还是不太懂..

线程安全性的文档化

线程安全,线程不安全. 不可变类和有条件线程安全都是线程安全的.在编写有条件线程安全的文档事,需要注意标明其使用场景.

© 著作权归作者所有

上一篇: Mysql简单操作
下一篇: springweb拦截器
流光韶逝
粉丝 21
博文 123
码字总数 143360
作品 0
济南
程序员
私信 提问

暂无文章

总结:TCP/IP协议

一、介绍 TCP协议属于OSI七层模型中的传输层协议,提供处于网络连接中的两台计算机之间的数据 传输。   在传输层有两个性质不同的协议:TCP(Transmission Control Protocol,传输控制协议...

浮躁的码农
3分钟前
0
0
一言不合就删库跑路?万名贡献者和阿里巴巴开源的二三事

9 月 27 日云栖大会,阿里巴巴宣布贾扬清担任开源技术委员会负责人。 有人问:开源是为了什么? 从个人视角看,可以证明自己的专业能力,获得行业认可; 从企业视角看,可以建立技术影响力,...

大涛学弟
14分钟前
1
0
JAVA编程注意事项(性能篇)

1. 尽量在合适的场合使用单例 使用单例可以缩短加载的时间,提高加载的效率,单例主要适用于以下三个方面: 第一,控制资源的使用,通过线程同步来控制资源的并发访问; 第二,控制实例的产生...

你好夜故事
15分钟前
1
0
List 前端 AngularJS JS 对IP排序

数据格式 $scope.dataList=[ {"ip":"192.168.10.10", "port":"8080",...}, { "ip":"192.168.10.12", "port":"8080",... } ,.....] 调用 $scope.ipSortForward($scope.dataList,"ip") 核心代码......

最菜最菜之小菜鸟
15分钟前
1
0
浅析Cassandra LeveledCompactionStrategy

前言 Cassandra是基于LSM架构的分布式数据库。LSM中有一个很重要的过程,就是压缩(Compaction)。默认的压缩策略是SizeTieredCompactionStrategy,今天主要说一下另一种压缩策略LeveledComp...

阿里云官方博客
20分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部