分类目录归档:未分类

java乐观锁和悲观锁

乐观锁和悲观锁没有孰优孰略,只是各自的应用场景不同。

乐观锁适用于写比较少(冲突比较小)的场景,因为不用上锁、释放锁,省去了锁的开销,从而提升了吞吐量。

如果是写多读少的场景,即冲突比较严重,线程间竞争激励,使用乐观锁就是导致线程不断进行重试,这样可能还降低了性能,这种场景下使用悲观锁就比较合适

乐观锁举例:

乐观锁可以使用版本号机制CAS算法实现。在 Java 语言中 java.util.concurrent.atomic包下的原子类就是使用CAS 乐观锁实现的。

悲观锁举例:

在 Java 语言中 synchronized 和 ReentrantLock等就是典型的悲观锁,还有一些使用了 synchronized 关键字的容器类如 HashTable 等也是悲观锁的应用。

了解java指令的重排序

java中编写的代码,不一定会顺序执行

例如在三段行看似“无关联”代码。

//假设为静态变量
static int a=0;
static boolean b=false;

//赋值

a=2;
b=true;

// 这是一个看似无关联代码(另一个线程)
if(b){
    System.out.println(a+a);
}

关于a,b的使用,肯定在声明之后,因为有明确的依赖性。

而a,b的再次使用之间则没有明确关联。

假如执行a,b赋值后立刻执行if,那么得到的输出是4

假设执行的是b赋值然后if,那么得到输出0。(正常情况下,b为true就是4)

由此可以看到java指令重排序带来了一些灾难。

如果使用volatile修饰变量,则有以下效果:

1. volatile写之前的操作不会被重排序到volatile写之后。

2. volatile读之后的操作不会被重排序到volatile读之前。

3. 前边是volatile写,后边是volatile读,这两个操作不能重排序。

简单了解jvm调优

jvm调优主要指gc调优

gc是指垃圾自动回收器。

gc调优主要是为了优化“堆”中的内存。(标准的虚拟机一般有堆,栈,方法区)

垃圾回收算法大部分使用:分代收集

堆中的内存可以分为“新生代”,“老年代”,“持久代”,注意“持久代”相当于方法区,用于存储一些几乎不变动的内容,这里不讨论“持久代”

新生代可以分为三个区eden,s0,s1,老年代没有分区。

刚创建的对象就在新生代的eden,这是gc频繁光顾的区域,随着新生代eden爆满或到达时间,就发生一次gc,此时存活下来的就往右移进入s0,在总共达到15次后进入老年代。

一些大对象,也会直接进入老年区,此外有很多复杂的情况不做介绍。

那么gc调优是什么意思?

无论是新生代,还是老年代,都有可能爆满,此时就是引发大清除,每次产生大清除时会耗费大量的性能,甚至可能造成应用暂停。

gc调优就是为了减少这种情况,调节新生代,老年代的比例,合适的比例能减少jvm不必要的损耗。