JAVA注解
-
@SuppressWarnings
用于抑制编译器产生警告信息
@SuppressWarnings(unuse)
&@SuppressWarnings(uncheck)
,其注解目标为类、字段、函数、函数入参、构造函数和函数的局部变量。而家建议注解应声明在最接近警告发生的位置。 -
@Override 表示当前方法覆盖了父类的方法
- @Deprecation 表示方法已经过时,方法上有横线,使用时会有警告。
Java多线程系列--锁
Synchronized
Synchronized是java关键字,属于内置特性.属于悲观锁.如果一个代码块被synchronized修饰了,当一个线程获取了对应的锁,并执行该代码块时,其他线程便只能一直等待,等待获取锁的线程释放锁,而这里获取锁的线程释放锁只会有两种情况:
- 获取锁的线程执行完了该代码块,然后线程释放对锁的占有
- 线程执行发生异常,此时JVM会让线程自动释放锁
Lock
Lock不是java关键字,属于JAVA类
- Lock不是Java语言内置的,synchronized是Java语言的关键字,因此是内置特性。Lock是一个类,通过这个类可以实现同步访问;
- Lock和synchronized有一点非常大的不同,采用synchronized不需要用户去手动释放锁,当synchronized方法或者synchronized代码块执行完之后,系统会自动让线程释放对锁的占用;而Lock则必须要用户去手动释放锁,如果没有主动释放锁,就有可能导致出现死锁现象。
分类:可重入锁,可中断锁, 公平锁, 读写锁, 偏向锁, 乐观锁, 悲观锁
Lock和Synchronized的选择
- Lock是一个接口,而synchronized是Java中的关键字,synchronized是内置的语言实现;
- synchronized在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象发生;而Lock在发生异常时,如果没有主动通过unLock()去释放锁,则很可能造成死锁现象,因此使用Lock时需要在finally块中释放锁;
- Lock可以让等待锁的线程响应中断,而synchronized却不行,使用synchronized时,等待的线程会一直等待下去,不能够响应中断;
- 通过Lock可以知道有没有成功获取锁,而synchronized却无法办到。
- Lock可以提高多个线程进行读操作的效率。
在性能上来说,如果竞争资源不激烈,两者的性能是差不多的,而当竞争资源非常激烈时,此时Lock的性能要远远优于Synchronized.
Java多线程系列--原子类
JAVA5中的java.util.concurrent包下面有一个atomic子包,其中有几个以Atomic打头的类,可以用非阻塞的方式完成原子操作. 根据修改的数据类型.可以将juc包中的原子操作分为4类:
- 基本类型: AtomicInteger,AtomicLong, AtomicBoolean
- 数组类型: AtomicIntegerArray,AtomicLongArray, AtomicReferenceArray
- 引用类型: AtomicReference,AtomicStampedRerence, AtomicMarkableReference
- 对象的属性修改类型: AtomicIntegerFieldUpdater, AtomicLongFieldUpdater, AtomicReferenceFieldUpdater
这些类存在的目的是对相应的数据进行原子操作.所谓原子操作,就是操作的过程中不会被中断,保证数据是以原子方式进行的
AtomicLong类的incrementAndGet()方法:
public final long incrementAndGet() {
for (;;) {
// 获取AtomicLong当前对应的long值
long current = get();
// 将current加1
long next = current + 1;
// 通过CAS函数,更新current的值
if (compareAndSet(current, next))
return next;
}
}
// value是AtomicLong对应的long值,该值是volatile类型的变量
private volatile long value;
// 返回AtomicLong对应的long值
public final long get() {
return value;
}
//incrementAndGet()接着将current加1,然后通过CAS函数,将新的值赋值给value
public final boolean compareAndSet(long expect, long update) {
return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
}
CAS 操作(Compare and Swap)乐观锁.CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。
非阻塞算法:
一个线程的失败或者挂起不应该影响其他线程的失败或者挂起的算法.
Java多线程系列--ThreadLocal类
用于保存独立的变量.对于一个线程类,当使用ThreadLocal维护变量时候,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所有每个线程都可以独立的改变自己的副本,而不会影响其他线程所对应的副本.通常用于用户登录控制.