相同代码,在统信64位系统,龙井jdk8下。
在eclipse中的结果,是偏向锁:
在终端中的结果,是轻量锁:
这是为什么呢?
这是代码:
package zhc.layout;
import org.openjdk.jol.info.ClassLayout;
public class App
{
public static void main( String[] args )
{
Object obj = new Object();
// 第一个线程
new Thread(()->{
synchronized (obj) {
System.out.println("------------------ 1------------------"+ Thread.currentThread().getId() );
System.out.println(ClassLayout.parseInstance(obj).toPrintable());
}
}, "Thread-bias").start();
// 等3秒开启下一个线程
try {
Thread.sleep(3000);
} catch (InterruptedException e1) {
System.out.println(e1);
}
// 第二个线程
new Thread(()->{
synchronized (obj) {
System.out.println("------------------ check 2------------------"+ Thread.currentThread().getId());
System.out.println(ClassLayout.parseInstance(obj).toPrintable());
try { // 5秒后结束本线程
Thread.sleep(5000);
} catch (InterruptedException e1) {
System.out.println(e1);
}
}
} , "Thread-check").start();
// 等3秒开启下一个线程
try {
Thread.sleep(3000);
} catch (InterruptedException e1) {
System.out.println(e1);
}
// 第三个线程
new Thread(()->{
synchronized (obj) {
System.out.println("------------------ 3------------------"+ Thread.currentThread().getId());
System.out.println(ClassLayout.parseInstance(obj).toPrintable());
}
} , "Thread-3").start();
// 最后结束主线程
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
System.out.println(e);
}
System.out.println("main end");
}
}
基本解决了。原因是jdk版本问题。
我在代码前面,sleep一会再执行,这样在终端中也是偏向锁。众所周知默认参数下,程序运行几秒后才会开启偏向模式。这证明原来的代码,原来的命令行参数无效,虽然也没报错说不认识参数。
作为佐证我在终端,改成龙井11的java运行原来的代码和原来的参数,直接就是偏向锁了。
不只是龙井,oracle8也一样对那2个参数无效
遗留问题:eclipse中的installed jre只有jdk8,为啥eclipse中运行就是偏向模式呢?
我还是问一个更重要的问题吧!!!
线程1执行后的markword,和线程2的markword一样,但是到线程3就不一样了!
我的疑问是线程2和3,面对同样的markword,是如何判断应该保持偏向锁?还是应该升级重量锁的?