多线程用到的概念知识点

http://ifeve.com/concurrenthashmap/

并发编程网:

concurrentHashMap:详细介绍

 1、实现原理:锁分段机制。

 concurrentHashMap ----> segment ---> hashEntry 

将map分为多个数据段,每段数据只能由一个线程访问,当多个线程访问entry数据时,只锁住这个entry所在的段,其他段的数据 仍然可以被其他线程访问。

2、好处: 在多线程情况下提高效率。

3、在读取数据时,不需要加锁。

valitile修饰变量 count 和value。 

具有原子性和可见性。

get操作的高效之处在于整个get过程不需要加锁,除非读到的值是空的才会加锁重读,我们知道HashTable容器的get方法是需要加锁的,那么ConcurrentHashMap的get操作是如何做到不加锁的呢?原因是它的get方法里将要使用的共享变量都定义成volatile,如用于统计当前Segement大小的count字段和用于存储值的HashEntry的value。定义成volatile的变量,能够在线程之间保持可见性,能够被多线程同时读,并且保证不会读到过期的值,但是只能被单线程写(有一种情况可以被多线程写,就是写入的值不依赖于原值),在get操作里只需要读不需要写共享变量count和value,所以可以不用加锁。之所以不会读到过期的值,是根据java内存模型的happen before原则,对volatile字段的写入操作先于读操作,即使两个线程同时修改和获取volatile变量,get操作也能拿到最新的值,这是用volatile替换锁的经典应用场景。

put:需要加锁

size不加锁,先将所有segment中的count值相加,然后再重复计算两次count值,若两次计算的值不一致,就将各个段都锁住,再进行计算。

writeOnArrayList:

http://ifeve.com/java-copy-on-write/

相当于arraylist,应用于并发编程,每次写入数据都对元数据进行复制,写入成功后,再将原数据的引用指向新数据。

使用与多次读操作。(注:每次读的是原来的数据。不能实时读)

ExecutorService: 创建线程池:(4种创建方法)

http://www.journaldev.com/1069/threadpoolexecutor-java-thread-pool-example-executorservice

ThreadPoolExecutor:

future 和futureTask:

http://www.tuicool.com/articles/m26Vzm

        futrure可以返回一个任务的生命周期。

runnable 不能返回值,能将数据写入文件。executor 实现了runnable

callable能返回值,能抛出异常。

 Executor框架使用Runnable 作为其基本的任务表示形式。Runnable是一种有局限性的抽象,然后可以写入日志,或者共享的数据结构,但是他不能返回一个值。

许多任务实际上都是存在延迟计算的:执行数据库查询,从网络上获取资源,或者某个复杂耗时的计算。对于这种任务,Callable是一个更好的抽象,他能返回一个值,并可能抛出一个异常。

Future表示一个任务的周期,并提供了相应的方法来判断是否已经完成或者取消,以及获取任务的结果和取消任务。

注:公司的console项目,多线程管理是通过继承Thread来执行任务的,将任务信息存储进ArrayBlockingQueue,并定时将任务queue中的数据写到数据库。
完成多线程的管理。

        采集器的实现:启动一个多线程,轮询ThreadPoolExecutor的executor,查看线程池的执行情况:

java中线程池的监控可以检测到正在执行的线程数。

// 通过线程池提供的参数进行监控。线程池里有一些属性在监控线程池的时候可以使用

// taskCount:线程池需要执行的任务数量。

// completedTaskCount:线程池在运行过程中已完成的任务数量。小于或等于taskCount。

// largestPoolSize:线程池曾经创建过的最大线程数量。通过这个数据可以知道线程池是否满过。如等于线程池的最大大小,则表示线程池曾经满了。

// getPoolSize:线程池的线程数量。如果线程池不销毁的话,池里的线程不会自动销毁,所以这个大小只增不- 

// getActiveCount:获取活动的线程数。

// 通过扩展线程池进行监控。通过继承线程池并重写线程池的beforeExecute,afterExecute和terminated方法,我们可以在任务执行前,执行后和线程池关闭前干一些事情。如监控任务的平均执行时间,最大执行时间和最小执行时间等。这几个方法在线程池里是空方法。如:

// protected void beforeExecute(Thread t, Runnable r) { }

System.out.println("monitor begin....");

System.out.println(String.format(

"[monitor] [%d/%d] Active: %d, Completed: %d, Task: %d, isShutdown: %s, isTerminated: %s",

this.executor.getPoolSize(), this.executor.getCorePoolSize(), this.executor.getActiveCount(),

this.executor.getCompletedTaskCount(), this.executor.getTaskCount(), this.executor.isShutdown(),

this.executor.isTerminated()));


ScheduledExecutorService 类,定时器类



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值