多线程:synchronized代码块、synchronized方法、静态synchronized方法使用的锁
在学习多线程的过程中,很多资料都会指出synchronized代码块和synchronized方法使用的锁都是this ,静态synchronized方法使用的锁是类锁,那么从这个结论出发,如何进行逆向证明呢?
证明this锁
``
public class ThreadDemo3 {
public static void main(String[] args) throws InterruptedException{
MyThread3 mt = new MyThread3();
Thread t1 = new Thread(mt, "窗口1");
Thread t2 = new Thread(mt, "窗口2");
t1.start();
Thread.sleep(40);
mt.flag = false;
t2.start();
}
}
class MyThread3 implements Runnable {
int tickets = 100;
boolean flag = true;
Object obj = new Object();
public void run() {
if (flag) {
while (tickets > 0) {
synchronized (obj) {
if (tickets > 0) {
try {
Thread.sleep(40);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "售出了" + (100 - tickets + 1) + "张票");
tickets--;
}
}
}
} else {
while (tickets > 0) {
sell();
}
}
}
synchronized public void sell() {
if (tickets > 0) {
try {
Thread.sleep(40);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "售出了" + (100 - tickets + 1) +"张票");
tickets--;
}
}
}
代码如上,简单说明下思路,synchronized同步代码块用obj作为锁的时候,打印的结果:两个线程随机打印,从第1张票卖到101张,说明出现了线程不安全问题,从而可以得出线程t1和t2没有同步执行的结论;
再把同步代码块中的锁改成this对象,再次执行,打印的结果为:两个线程随机打印,从第1张票卖到100张。
证明类锁
把上面的代码再稍作修改,将sell方法,flag对象,tickets对象加上static修饰符,再次运行代码,可以看到结果又打印了101张票,说明静态方法使用的并非this锁,我们根据结论,把synchronized同步代码块里的锁换成"MyThread3.class"再运行程序,同步现象出现!
这样一来就可以验证开头的结论了
做个小总结,在写这段代码的过程中,犯了一个问题,把while循环写到了synchronized代码块中,这样做会导致线程同步以后,变成单线程执行,线程t2永远不会获得执行的机会!!所以一定要注意在多线程编码过程中,同步代码块的范围
posted on 2020-01-07 22:58 nameless_vi 阅读(513) 评论(0) 编辑 收藏 举报