文章作者:匠心零度
http://my.csdn.net/lirenzuo
原文链接:
http://blog.csdn.net/lirenzuo/article/details/78253481
无意中了解到如下题目,觉得蛮好。
题目如下:
public class TestSync2 implements Runnable {
int b = 100;
synchronized void m1() throws InterruptedException {
b = 1000;
Thread.sleep(500); //6
System.out.println("b=" + b);
}
synchronized void m2() throws InterruptedException {
Thread.sleep(250); //5
b =
2000;
}
public static void main(String[] args) throws InterruptedException {
TestSync2 tt = new TestSync2();
Thread t = new Thread(tt); //1
t.start(); //2
tt.m2(); //3
System.out.println("main thread b=" + tt.b); //4
}
@Override
public void run() {
try {
m1();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
该程序的输出结果?
程序输出结果:
main thread b=2000
b=1000
或
main thread b=1000
b=1000
考察知识点
-
synchronize实例锁。
-
并发下的内存可见性。
在java中,多线程的程序最难理解、调试,很多时候执行结果并不像我们想象的那样执行。所以在java多线程特别难,依稀记得大学的时候考c语言二级的时候,里面的题目是什么++和很多其他优先级的符合在一起问最后的输出结果,这类题目就想考一些运行符优先级和结合性问题。那个背背就行了,但是java多线程还是需要好好理解才行,靠背是不行的。
下面开始简单分析
该题目涉及到2个线程(主线程main、子线程)、关键词涉及到synchronized、Thread.sleep。
synchronized关键词还是比较复杂的(可能有时候没有理解到位所以上面题目会有点误区),他的作用就是实现线程的同步(实现线程同步有很多方法,它只是一种后续文章会说其他的,需要好好研究大神Doug Lea的一些实现),它的工作就是对需要同步的代码加锁,使得每一次只有一个线程可以进入同步块(其实是一种悲观策略)从而保证线程只记得安全性。
一般关键词synchronized的用法