
| Object Header (64 bits) | |
| Mark Word (32 bits) | Klass Word (32 bits) |
| Object Header (96 bits) | ||
| Mark Word(32bits) | Klass Word(32bits) | array length(32bits) |
| Mark Word (32 bits) | State | ||||
| identity_hashcode:25 | age:4 | biased_lock:1 | lock:2 | Normal | |
| thread:23 | epoch:2 | age:4 | biased_lock:1 | lock:2 | Biased |
| ptr_to_lock_record:30 | lock:2 | LightweightLocked | |||
| ptr_to_heavyweight_monitor:30 | lock:2 | HeavyweightLocked | |||
| lock:2 | Marked for GC |
| biased_lock | lock | 状态 |
| 0 | 01 | 无锁 |
| 1 | 01 | 偏向锁 |
| 0 | 00 | 轻量级锁 |
| 0 | 10 | 重量级锁 |
| 0 | 11 | GC标记 |

static final Object lock = new Object();
static int counter = 0;
public static void main(String[] args) {
synchronized (lock) {
counter++;
}
}static final Object obj = new Object();
public static void method1() {
synchronized (obj) { // 同步块 A
method2();
}
}
public static void method2() {
synchronized (obj) { // 同步块 B
}
}






| 线程1(core 1上) | 对象Mark | 线程2(core 2 上) |
| - | 10(重量锁) | - |
| 访问同步块,获取Monitor | 10(重量锁)重量锁指针 | - |
| 成功(加锁) | 10(重量锁)重量锁指针 | - |
| 执行同步块 | 10(重量锁)重量锁指针 | - |
| 执行同步块 | 10(重量锁)重量锁指针 | 访问同步块,获取Monitor |
| 执行同步块 | 10(重量锁)重量锁指针 | 自旋重试 |
| 执行完毕 | 10(重量锁)重量锁指针 | 自旋重试 |
| 成功(解锁) | 01(无锁) | 自旋重试 |
| - | 10(重量锁)重量锁指针 | 成功(加锁) |
| - | 10(重量锁)重量锁指针 | 执行同步块 |
| - | … | … |
| 线程1(core 1上) | 对象Mark | 线程2(core 2 上) |
| - | 10(重量锁) | - |
| 访问同步块,获取Monitor | 10(重量锁)重量锁指针 | - |
| 成功(加锁) | 10(重量锁)重量锁指针 | - |
| 执行同步块 | 10(重量锁)重量锁指针 | - |
| 执行同步块 | 10(重量锁)重量锁指针 | 访问同步块,获取Monitor |
| 执行同步块 | 10(重量锁)重量锁指针 | 自旋重试 |
| 执行同步块 | 10(重量锁)重量锁指针 | 自旋重试 |
| 执行同步块 | 10(重量锁)重量锁指针 | 自旋重试 |
| 执行同步块 | 10(重量锁)重量锁指针 | 阻塞 |
| - | … | … |
static final Object obj = new Object();
public static void m1() {
synchronized (obj) { // 同步块 A
m2();
}
}
public static void m2() {
synchronized (obj) { // 同步块 B
m3();
}
}
public static void m3() {
synchronized (obj) {
}
}

| Mark Word (32 bits) | State | ||||
| identity_hashcode:25 | age:4 | biased_lock:1 | lock:2 | Normal | |
| thread:23 | epoch:2 | age:4 | biased_lock:1 | lock:2 | Biased |
| ptr_to_lock_record:30 | lock:2 | LightweightLocked | |||
| ptr_to_heavyweight_monitor:30 | lock:2 | HeavyweightLocked | |||
| lock:2 | Marked for GC |
public synchronized static void main(String[] args){
log.info("{}", toSimplePrintable(object));
}private static Object object = new Object();
public synchronized static void main(String[] args){
new Thread(()->{
log.info("{}", "synchronized前");
log.info("{}", toSimplePrintable(object));
synchronized (object){
log.info("{}", "synchronized中");
log.info("{}", toSimplePrintable(object));
}
log.info("{}", "synchronized后");
log.info("{}", toSimplePrintable(object));
},"t1").start();
}private static Object object = new Object();
public synchronized static void main(String[] args){
object.hashCode();//调用hashcode
new Thread(()->{
log.info("{}", "synchronized前");
log.info("{}", toSimplePrintable(object));
synchronized (object){
log.info("{}", "synchronized中");
log.info("{}", toSimplePrintable(object));
}
log.info("{}", "synchronized后");
log.info("{}", toSimplePrintable(object));
},"t1").start();
}private static void test2() {
Thread t1 = new Thread(() -> {
synchronized (object) {
log.info("{}", toSimplePrintable(object));
}
synchronized (MyClass03.class) {
MyClass03.class.notify();//t1执行完之后才通知t2执行
}
}, "t1");
t1.start();
Thread t2 = new Thread(() -> {
synchronized (MyClass03.class) {
try {
MyClass03.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
log.info("{}", toSimplePrintable(object));
synchronized (object) {
log.info("{}", toSimplePrintable(object));
}
log.info("{}", toSimplePrintable(object));
}, "t2");
t2.start();
}private static void test3(){
Thread t1 = new Thread(() -> {
log.info("{}", toSimplePrintable(object));
synchronized (object) {
log.info("{}", toSimplePrintable(object));
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
log.info("{}", toSimplePrintable(object));
}
}, "t1");
t1.start();
new Thread(() -> {
try {
Thread.sleep(6000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (object) {
log.debug("notify");
object.notify();
}
}, "t2").start();
}public static class Dog{}
private static void test4() {
Vector<Dog> list = new Vector<>();
Thread t1 = new Thread(() -> {
for (int i = 0; i < 30; i++) {
Dog d = new Dog();
list.add(d);
synchronized (d) {
log.info("{}", i+"\t"+toSimplePrintable(d));
}
}
synchronized (list) {
list.notify();
}
}, "t1");
t1.start();
Thread t2 = new Thread(() -> {
synchronized (list) {
try {
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
log.debug("===============> ");
for (int i = 0; i < 30; i++) {
Dog d = list.get(i);
log.info("{}", i+"\t"+toSimplePrintable(d));
synchronized (d) {
log.info("{}", i+"\t"+toSimplePrintable(d));
}
log.info("{}", i+"\t"+toSimplePrintable(d));
}
}, "t2");
t2.start();
}

static Thread t1, t2, t3;
private static void test6() throws InterruptedException {
Vector<Dog> list = new Vector<>();
int loopNumber = 40;
t1 = new Thread(() -> {
for (int i = 0; i < loopNumber; i++) {
Dog d = new Dog();
list.add(d);
synchronized (d) {
log.info("{}", i + "\t" + toSimplePrintable(d));
}
}
LockSupport.unpark(t2);
}, "t1");
t1.start();
t2 = new Thread(() -> {
LockSupport.park();
log.debug("===============> ");
for (int i = 0; i < loopNumber; i++) {
Dog d = list.get(i);
log.info("{}", i + "\t" + toSimplePrintable(d));
synchronized (d) {
log.info("{}", i + "\t" + toSimplePrintable(d));
}
log.info("{}", i + "\t" + toSimplePrintable(d));
}
LockSupport.unpark(t3);
}, "t2");
t2.start();
t3 = new Thread(() -> {
LockSupport.park();
log.debug("===============> ");
for (int i = 0; i < loopNumber; i++) {
Dog d = list.get(i);
log.info("{}", i + "\t" + toSimplePrintable(d));
synchronized (d) {
log.info("{}", i + "\t" + toSimplePrintable(d));
}
log.info("{}", i + "\t" + toSimplePrintable(d));
}
}, "t3");
t3.start();
t3.join();
log.info("{}", toSimplePrintable(new Dog()));
}
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当
这里是Ruby新手。完成一些练习后碰壁了。练习:计算一系列成绩的字母等级创建一个方法get_grade来接受测试分数数组。数组中的每个分数应介于0和100之间,其中100是最大分数。计算平均分并将字母等级作为字符串返回,即“A”、“B”、“C”、“D”、“E”或“F”。我一直返回错误:avg.rb:1:syntaxerror,unexpectedtLBRACK,expecting')'defget_grade([100,90,80])^avg.rb:1:syntaxerror,unexpected')',expecting$end这是我目前所拥有的。我想坚持使用下面的方法或.join,
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm
我们的git存储库中目前有一个Gemfile。但是,有一个gem我只在我的环境中本地使用(我的团队不使用它)。为了使用它,我必须将它添加到我们的Gemfile中,但每次我checkout到我们的master/dev主分支时,由于与跟踪的gemfile冲突,我必须删除它。我想要的是类似Gemfile.local的东西,它将继承从Gemfile导入的gems,但也允许在那里导入新的gems以供使用只有我的机器。此文件将在.gitignore中被忽略。这可能吗? 最佳答案 设置BUNDLE_GEMFILE环境变量:BUNDLE_GEMFI
这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub
我正在玩HTML5视频并且在ERB中有以下片段:mp4视频从在我的开发环境中运行的服务器很好地流式传输到chrome。然而firefox显示带有海报图像的视频播放器,但带有一个大X。问题似乎是mongrel不确定ogv扩展的mime类型,并且只返回text/plain,如curl所示:$curl-Ihttp://0.0.0.0:3000/pr6.ogvHTTP/1.1200OKConnection:closeDate:Mon,19Apr201012:33:50GMTLast-Modified:Sun,18Apr201012:46:07GMTContent-Type:text/plain
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www
我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我