针对我们上一章所提到过的多线程卖票问题,这里我们调整下代码,模拟出买票过程所占用的时间,这时候我们就会发现票数出现了-1张
例:
注:sleep为thread类静态方法如下:
public static void sleep (long millis) thorows InterruptedException
出现负数票的原因:
当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完另一个线程就参与进来执行。导致共享数据的错误。
因此为了解决这个问题,我们对多条操作共享数据的语句,只能让一个线程都执行完。在执行过程中,其他线程不可以参与执行。
同步代码块:
同步方法就是在方法前加关键字synchronized,然后被同步的方法一次只能有一个线程进入,其他线程等待
synchronized(obj){
代码块
}
同步方法:
同步代码块则是在方法内部使用大括号使得一个代码块得到同步。 同步块会有 一个对象
模拟两个用户向银行中存钱
验证同步函数的锁是this:
如下图所示,我们通过变量flag将两个线程分开。
我们惊讶的发现所有的买票程序都是走show方法而不是同步代码块,这是因为主线程瞬间执行完
(1)开启t1线程(2)flag修改为false(3)开始t2线程
然后t1,t2线程处于临时状态(有资格但是没有执行权,因为执行权在主线程上)
但是我们又发现票数出现了 0张票,这就说明同步方法和同步代码块的锁不是同一个(代码块使用obj锁)
将同步代码块的obj对象改为this后,我们发现0票现象已经修正
验证同步函数被静态修饰后的锁是:类名.class
通过验证,我们发现它不再使用this,因为静态方法中不可以定义this
静态进内存时,内存中没有本类对象,但是一定会有该类对应的字节码文件对象 类名.class
网友评论