## 位操作&最高位 ```java publicstaticinthighestOneBit(int i) { // HD, Figure 3-1 i |= (i >> 1);//右移一位, i |= (i >> 2); i |= (i >> 4); i |= (i >> 8); i |= (i >> 16); return i - (i >>> 1);// }
publicstaticintnumberOfLeadingZeros(int i) { // HD, Figure 5-6 if (i == 0) return32; intn=1; if (i >>> 16 == 0) { n += 16; i <<= 16; }//无符号右移16 高16位==0(i左移16位保存低16位,舍弃高16位) if (i >>> 24 == 0) { n += 8; i <<= 8; }//无符号右移24 高8位==0 if (i >>> 28 == 0) { n += 4; i <<= 4; }// if (i >>> 30 == 0) { n += 2; i <<= 2; } n -= i >>> 31; return n; } ``` **Result:** ```jshell> Integer.toString(Integer.numberOfLeadingZeros(0x1),10) $8 ==> "31" jshell> Integer.toString(Integer.numberOfLeadingZeros(0xffffffff),10) $10 ==> "0" jshell> Integer.toString(Integer.numberOfLeadingZeros(0x3fffffff),10) $11 ==> "2" jshell> Integer.toString(Integer.numberOfLeadingZeros(0x1fffffff),10) $12 ==> "3"
位操作&低位零的数目
1 2 3 4 5 6 7 8 9 10 11
publicstaticintnumberOfTrailingZeros(int i) { // HD, Figure 5-14 int y; if (i == 0) return32; intn=31; y = i <<16; if (y != 0) { n = n -16; i = y; }//低十六位!=0 -=16 y = i << 8; if (y != 0) { n = n - 8; i = y; } y = i << 4; if (y != 0) { n = n - 4; i = y; } y = i << 2; if (y != 0) { n = n - 2; i = y; } return n - ((i << 1) >>> 31); }
publicstaticintrotateLeft(int i, int distance) {//循环左移 return (i << distance) | (i >>> -distance);//左移|移出的补位 } publicstaticintrotateRight(int i, int distance) {//循环右移 return (i >>> distance) | (i << -distance);//无符号右移|移出的补位 }
publicstaticintreverse(int i) { // HD, Figure 7-1 i = (i & 0x55555555) << 1 | (i >>> 1) & 0x55555555; i = (i & 0x33333333) << 2 | (i >>> 2) & 0x33333333; i = (i & 0x0f0f0f0f) << 4 | (i >>> 4) & 0x0f0f0f0f; i = (i << 24) | ((i & 0xff00) << 8) | ((i >>> 8) & 0xff00) | (i >>> 24); return i; }
位操作&二进制中1的数目
1 2 3 4 5 6 7 8 9
publicstaticintbitCount(int i) { // HD, Figure 5-2 i = i - ((i >>> 1) & 0x55555555); i = (i & 0x33333333) + ((i >>> 2) & 0x33333333); i = (i + (i >>> 4)) & 0x0f0f0f0f; i = i + (i >>> 8); i = i + (i >>> 16); return i & 0x3f; }
第三步i = (i + (i >>> 4)) & 0x0f0f0f0f;(0f的二进制为00001111)中i + (i >>> 4)得到的结果为: $i + (i >>> 4)=((b_0+b_1+b_2+b_3)\cdot2^0+(b_4+b_5+b_6+b_7)\cdot2^4+…\ +(b_{24}+b_{25}+b_{26}+b_{27})\cdot2^{24}+(b_{28}+b_{29}+b_{30}+b_{31})\cdot2^{28})\ +((b_4+b_5+b_6+b_7)\cdot2^0+(b_8+b_9+b_{10}+b_{11})\cdot2^4+…+(b_{28}+b_{29}+b_{30}+b_{31})\cdot2^{24})\ =(b_0+b_1+b_2+…+b_6+b_7)\cdot2^0+(b_4+b_5+b_6+…+b_{10}+b_{11})\cdot2^4+…\ +(b_{24}+b_{25}+b_{26}+…+b_{30}+b_{31})\cdot2^{24}+(b_{28}+b_{29}+b_{30}+b_{31})\cdot2^{28}$
所以i = (i + (i >>> 4)) & 0x0f0f0f0f;得到的结果为: $i=(b_0+b_1+b_2+…+b_6+b_7)\cdot2^0+(b_8+b_9+b_{10}+b_{11}+…+b_{14}+b_{15})\cdot2^8+…+(b_{24}+b_{25}+b_{26}+…+b_{30}+b_{31})\cdot2^{24}$
第四步i = i + (i >>> 8);得到的结果为: $i=(b_0+b_1+b_2+…+b_{14}+b_{15})\cdot2^0+(b_8+b_9+b_{10}+…+b_{22}+b_{23})\cdot2^8\ +(b_{16}+b_{17}+b_{18}+…+b_{30}+b_{31})\cdot2^{16}+(b_{24}+b_{25}+b_{26}+…+b_{30}+b_{31})\cdot2^{24}$
第五步i = i + (i >>> 16);得到的结果为: $i=(b_0+b_1+b_2+…+b_{30}+b_{31})\cdot2^0+(b_8+b_9+b_{10}+…+b_{30}+b_{31})\cdot2^8\ +(b_{16}+b_{17}+b_{18}+…+b_{30}+b_{31})\cdot2^{16}+(b_{24}+b_{25}+b_{26}+…+b_{30}+b_{31})\cdot2^{24}$
最后i & 0x3f;得到的结果为: $i=\sum_{i=0}^{31}b_i$
AtomicInteger
An int value that may be updated atomically.
An AtomicInteger is used in applications such as atomically incremented counters, and cannot be used as a replacement for an java.lang.Integer. However, this class does extend Number to allow uniform access by tools and utilities that deal with numerically-based classes.
publicclassAtomicIntegerextendsNumberimplementsjava.io.Serializable { // setup to use Unsafe.compareAndSwapInt for updates privatestaticfinalUnsafeunsafe= Unsafe.getUnsafe();
////////////////////////////About AtomicInteger///////////////////////////////////////// publicnativevoidputOrderedInt(Object var1, long offset, int newValue); publicfinalnativebooleancompareAndSwapInt(Object var1, long offset, int expect, int update);//Value(var1.offset)==expect?{Value(var1.offset)=update; return true;}:return false; publicfinalintgetAndAddInt(Object var1, long offset, int addon) { int current; do { current = this.getIntVolatile(var1, offset);//取出当前值 } while(!this.compareAndSwapInt(var1, offset, current, current + addon));//set the new value successfully ? true : false; return current; } }
阻塞同步和非阻塞同步都是实现线程安全的两个保障手段,非阻塞同步对于阻塞同步而言主要解决了阻塞同步中线程阻塞和唤醒带来的性能问题,那什么叫做非阻塞同步呢? 在并发环境下,某个线程对共享变量先进行操作,如果没有其他线程争用共享数据那操作就成功;如果存在数据的争用冲突,那就采取补偿措施,比如不断的重试机制,直到成功为止,因为这种乐观的并发策略不需要把线程挂起,也就把这种同步操作称为非阻塞同步(操作和冲突检测具备原子性)。在硬件指令集的发展驱动下,使得 “操作和冲突检测” 这种看起来需要多次操作的行为只需要一条处理器指令便可以完成,这些指令中就包括非常著名的 CAS 指令(Compare-And-Swap 比较并交换)。 《深入理解 Java 虚拟机第二版. 周志明》第十三章中这样描述关于 CAS 机制: