将卖票的例子由原来的同步代码块改成同步函数
接下来用代码进行验证同步函数的锁是this这一结论
package com.javaxl.thread;
/**
* @author 小李飞刀
* @site www.javaxl.com
* @company
* @create 2019-05-29 11:09
*
* 多线程的安全问题
*
*/
public class Demo2 {
public static void main(String[] args) {
Ticket z = new Ticket();
Thread t1 = new Thread(z);
Thread t2 = new Thread(z);
t1.start();
// 这样能确保两个线程错开执行
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("------------------------------------");
z.flag = false;
t2.start();
// 用来论证线程安全的问题
// Thread t3 = new Thread(z);
// Thread t4 = new Thread(z);
// t3.start();
// t4.start();
}
}
class Ticket implements Runnable{
private int num = 10000000;
private Object obj = new Object();
// 制造两个线程在跑一个同步代码块的假象
// 同步代码块上的锁暂定为obj 我们发现会出现0这个数字,出现了并发问题
// 造成上面并发问题的原因就在于多线程用的不是同一把锁,也就意味着同步函数上的锁不是obj,这时我们在将同步代码块上的obj改成this
boolean flag = true;
@Override
public void run() {
if(flag){
synchronized (obj){
while (true){
if(num>0){
// try {
// Thread.sleep(60);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
System.out.println(Thread.currentThread().getName() + "同步代码块..sale........"+ num--);
}
}
}
}else {
while (true){
show();
}
}
}
public synchronized void show(){
if (num > 0){
// try {
// Thread.sleep(60);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
System.out.println(Thread.currentThread().getName() + "...sale......同步函数................"+ num--);
}
}
}
结果
两个线程被锁给锁定,这两个线程操作共享数据,如果线程不是被同一把锁控制,
那么两个线程还是可以同时操作同步代码块的内容,依然会引发并发问题。
如果同步函数被静态修饰后,使用的锁什么呢?
通过验证,发现不再是this,因为静态方法中也不可以定义this;
静态进内存时,内存中没有本类对象,但是一定有该类对应的字节码文件对象;
类名.class 该对象的类型是class
静态的同步函数,所用的锁是该方法所在类的字节码文件对象。类名.class
我们反过头再来看单例模式的懒汉式为什么这么写?
将上面例子简单改动
简单的死锁案例
相关代码
package com.javaxl.thread; /** * @author 小李飞刀 * @site www.javaxl.com * @company * @create 2019-05-29 21:12 * * 死锁 */ public class Demo3 { public static void main(String[] args) { SiThread s = new SiThread(); Thread t1 = new Thread(s); Thread t2 = new Thread(s); t1.start(); try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } s.flag = false; t2.start(); } } class MyLock{ static Lock locka = new Lock(); static Lock lockb = new Lock(); } class Lock{ } class SiThread implements Runnable{ boolean flag = true; @Override public void run() { if(flag){ while (true){ synchronized (MyLock.locka){ System.out.println("if locka"); synchronized (MyLock.lockb){ System.out.println("if lockb"); } } } }else { while (true){ synchronized (MyLock.lockb){ System.out.println("else lockb"); synchronized (MyLock.locka){ System.out.println("else locka"); } } } } } }
备案号:湘ICP备19000029号
Copyright © 2018-2019 javaxl晓码阁 版权所有