That
the
Fibonacci
lease number (斐波那契):
1、F(1) = F(2)=1 , F(N) = F(N-1) + F(N-2) , N >= 3
2、if n % 2 =1 and n!=0 and n>=2
F(N) * F(N) - 1 = F(N-1) * F(N+1);
3、if n % 2 =0 and n!=0 and n>=2
F(N) * F(N) + 1 = F(N-1) * F(N+1);
Atomic class:
introduction: object operation with syncchronized
原理:
public boolean compareAndSet (V expectedReference,//预期引用 V newReference, //更新后的引用 int expectedStamp, //预期标志 int newStamp) //更新后的标志
首先检查当前引用是否等于预期引用,并且当前标志是否等于预期标志,如果全部相等,则以原子方式将该引用和该标志的值设置为给定的更新值,否则不做处理
for example:
class Counter1 {
private int count = 0;
public synchronized void increment() {
count++; //to ensure that operation is safely require synchronized
}
public int getCount() {
return count.get();
}
}
class Counter2 {
private AtomicInteger count = new AtomicInteger();
public void increment() {
count.incrementAndGet(); //it does not require synchronized and it ensure the operation was safely
}
public int getCount() {
return count.get();
}
}
count++ operation is not thread safely ,it mabe make mistakes, and atumic can be safely and it will be fast
from the code shown here, there is no practical difference between the two code examples. If one thread modifies count "simultaneously" with another thread modifying count- so what? How is that observably different from one thread acting a tiny bit before, or a tiny bit after, the other? The operations defined in the synchonized code are identical in effect to the operations in the atomic code. As long as every synchronized method does no more than a single atmic method call can do, there is no real difference between the two coding techniques. Except that the atomic code is probably faster.
volatile variable:
具有synchronized的可见性特性(变量直接在内存中进行操作,不会操作缓存在虚拟机中的变量),但是不具备原子特性(可以被多个线程同时操作,易出现偏差),要确保volatile变量能提供理想的变量安全必须要满足两个条件,1、对变量的读写不依赖于当前值(比如i++之类的),2、该变量没有包含在其他变量的不变式中
volatile 读操作开销非常低 —— 几乎和非 volatile 读操作一样。而 volatile 写操作的开销要比非 volatile 写操作多很多(而且易出误差),因为要保证可见性需要实现内存界定(Memory Fence)
所以volatile可以和Synchronized配合使用:for example:
开销较低的读-写锁
public class CheesyCounter { // Employs the cheap read-write lock trick // All mutative operations MUST be done with the 'this' lock held @GuardedBy("this") private volatile int value; public int getValue() { return value; } public synchronized int increment() { return value++; } }
Transient:
1) 一旦变量被transient修饰,变量将不再是对象持久化的一部分,该变量内容在序列化后无法获得访问。
2) transient关键字只能修饰变量,而不能修饰方法和类。注意,本地变量是不能被transient关键字修饰的。变量如果是用户自定义类变量,则该类需要实现Serializable接口。
3)被transient关键字修饰的变量不再能被序列化,一个静态变量不管是否被transient修饰,均不能被序列化。
用途:
打个比方,如果一个用户有一些敏感信息(如密码,银行卡号等),为了安全起见,不希望在网络操作(主要涉及到序列化操作,本地序列化缓存也适用)中被传输,这些信息对应的变量就可以加上transient关键字。换句话说,这个字段的生命周期仅存于调用者的内存中而不会写到磁盘里持久化。
java位移动运算:
0x0f:0x是16进制,a=10,b=11,c=12,d=13,e=14,f=15,所以0x0f等于十进制的15
左移运算符<<:
左移运算符<<使指定值的所有位都左移规定的次数。value << num, num 指定要移位值value 移动的位数,左移的规则只记住一点:丢弃最高位,0补最低位
如果移动的位数超过了该类型的最大位数,那么编译器会对移动的位数取模。如对int型移动33位,实际上只移动了33%32=1位
数学意义 :
在数字没有溢出的前提下,对于正数和负数,左移一位都相当于乘以2的1次方,左移n位就相当于乘以2的n次方
在数字没有溢出的前提下,对于正数和负数,左移一位都相当于乘以2的1次方,左移n位就相当于乘以2的n次方
无符号右移>>>:
value >>> num,
忽略了符号位扩展,0补最高位,无符号右移运算符>>> 只是对32位和64位的值有意义
右移运算符>>:
value >> num,低位移出(舍弃),高位的空位补符号位,即正数补零,负数补1 ,例如,如果要移走的值为负数,每一次右移都在左边补1,
如果要移走的值为正数,每一次右移都在左边补0
数学意义 :
右移一位相当于除2,右移n位相当于除以2的n次方(正数)。
右移一位相当于除2,右移n位相当于除以2的n次方(正数)。