`
文章列表

线程数

      增加线程数可以提高应用的处理能力,但线程数过多,CPU频繁切换线程会影响性能。           最好的状态是一直使CPU一直保执忙碌状态,如果主机上有两颗四核CPU,那么至少需要8条线程,才能充分利用CPU,如果线程中有阻塞等待,就需要更多的线程供CPU调度执行,否则CPU闲置,如果线程执行相同的任务,阻塞时间与执行时间相等,那么就需要8*2=16条线程。即(阻塞时间/线程执行时间+1)*cpu核心数。             实际中线程执行的任务类型不同,阻塞时间也不相同,不好计算出线程数。 可以通过不同线程数下做压力测试来确认最佳线程数。      Runti ...
多线程中对某些共享变量进行读写操作,并发读操作时不会产生问题,并发读写或并发写操作会引起线程安全性问题。 下面代码会报错:java.util.ConcurrentModificationException   public class TestReentrantReadWriteLock { volatile Map dataMap = new HashMap(); private static TestReentrantReadWriteLock testReentraintReadWriteLock = new TestReentrantReadWriteLock(); ...

Condition

A线程在使用Lock获得锁的后,可能会由于某些条件不满足,而不能继续执行,需要等待条件满足时,可以使用 Condition,Lock接口有一个newCondition()方法实化Condition,调用 Condition.await()当前线程释放锁,进入阻塞状态,当B线程获得这个锁并使条件满足时,调用同一个Condition实例的notify或notifyAll方法时,A线程被唤醒,但并未执行,需要B线程释放锁之后,A线程能够得到锁,才从await之后的代码执行。    A线程调用Condition.await()方法之后, 如果A线程在进入await方法之前被中断,await立即 ...

ReentrantLock

ReentrantLock 是一个可重入的锁,用于线程之间的同步。  采用独占锁方式,即一个线程获得锁,其它线程需等待锁的释放。 ReentrantLock与内置锁synchronized相比,多了: 1.lockInterruptibly() 获取锁的过程中 可以响应中断并返回假   2. tryLock(long timeout, TimeUnit unit)  获取锁的过程中,可以响应中断并返回假、支持超时检测并返回假,   3.可以不在一个代码中,但要保证锁的释放       jdk1.5 中synchronized 性能没有 ReentrantLock好,jdk1. ...
    StringBuffer 是线程安全类   StringBuilder是非线程安全类,比 StringBuffer 要快。   StringBuffer  和StringBuilder  是AbstractStringBuilder的子类。     AbstractStringBuilder 内部有一个char数组,用于保存数据。   AbstractStringBuilder implements Appendable, CharSequence { char[] value;//保存char int count;//当前使用的长度 Abst ...
AbstractQueuedSynchronizer 是多线程实现同步的基类,采用先进先出线程队列,队列中存有某些线程,这些线程由于某些状态或条件不满足(例如未获得锁)而进入阻塞状态,当条件满足时(例如持有锁的线程释放了锁)先入队列的 ...

Unsafe

一.CAS(compare and swap)  Unsafe 用于实现CAS(compare and swap) 操作,基于CPU一条原始指令,是原子的线程安全的,可用于多线程间非阻塞方式实现线程安全。   多线程中如果有多个线程修改共享变量,一般使用synchronized ,只有一个线 ...

volatile

java 内存模型:     主内存:保存对象实例数据、数组等--对所有线程共享。     工作内存(缓存): 线程私有,线程执行时,从主内存获取变量副本,保存在工作内存,对其进行操作,操作完成之后再写入工作内存。       1.保证可见性         每条线程执行时都有有自己的工作内存,当对一个变量操作时,会从主内存中取出变量存入线程的工作内存,之后对该变量的读操作一直在线程工作内存中,工作内存中的变量发生变化时会写入主内存,但主内存的变量发生变化(可能由其它线程写入)时不一定及时的同步至工作内存中,这样就造成线程读取的变量还是以前的值。      变量声明为 vol ...

原子性

原子性操作是指不可分割的操作,不能被线程调度暂停的操作。   具有原子性的操作:    1.变量的赋值(long,double类型数据除外,含对象的引用变量)    2.volatile 标记的 long,double 类型数据赋值 原子性操作本身是线程安全的。    复合操作不具备原子性,如++1,value+=1,if(!map.containsKey(key))map.put(key,value);  

LockSupport

LockSupport 提供了使线程阻塞或恢复阻塞的方法。   LockSupport.park 使当前线程进入阻塞状态。 LockSupport.unpark(Thread thread) 使参数指定的线程从阻塞状态进入可运行状态   park和unpark方法内部调用Unsafe类的本地方法实现了线程的阻塞与恢复。    ReentrantLock  和 ReentrantReadWriteLock  内部使用 LockSupport  实现了线程阻塞的功能。     需要注意的是 LockSupport.park 使线程阻塞,未调用upark方法时,线程也有可能被唤 ...

atomic

  Atomic 包中的类提供了对数据进行原子操作的功能。 例如   a++ 、a+=1等类似代码不是原子的,实现过程是由内存中取出数据,对数据进行计算,再结果写入内存,属于复合操作,由多条CPU指令完成。   在单线程下这些代码会运行良好,如果a是多线程中的共享变量,那么运行结果可能会不正确。 举列: a表示一个累计值,以a++为例:    X线程 从内存中取出a的值=5,执行a++,得出的结果是6,并未写回内存时前,Y线程从内存中取出a的值=5,X线程将a=6写回内存,但Y缓存中a的值=5,执行a++得出结果为6,写回内存a=6。 结果是两个线程分别对5进行加1操作,但结果等于6 ...
Global site tag (gtag.js) - Google Analytics