前言
此博客为观看B老师Java视频后所记
文中涉及的多线程与同步代码块相关知识在此篇博客中有分析和举例 Java随笔记录(四)
问题描述
有两个客户到一个银行去存钱,每个客户存100元,存三次
问题:不使用同步代码块时是否有安全问题?有的话分析并解决
二、bug分析
未使用同步代码块之前代码:
// 描述银行
class Bank
{
private int sum;
public void add(int num)
{
sum = sum+num;
System.out.println("sum="+sum);//每村一次,打印金额的变化
}
}
class Customer implements Runnable
{
private Bank b = new Bank();
public void run()
{
for(int x=0;x<3;x++)
{
b.add(100); //一次存100
}
}
}
class ThreadDemo3
{
public static void main(String[] args)
{
Customer c = new Customer();
Thread t1 = new Thread(c);
Thread t2 = new Thread(c);
t1.start();
t2.start();
}
}
出现问题:打印顺序错乱,并且有几次数值错误,没有100.有时候结果正确
分析:以上现象说明多线程随机性造成了安全问题发生
- 既然是多线程问题,说明问题必然发生在线程任务中
- 代码中的b对象有共性数据sum,且 对sum进行了多次运算
加入同步代码块修改后的代码
// 描述银行
class Bank
{
private int sum;
private Object obj = new Object();
public void add(int num)
{
synchronized(obj)
{
sum = sum+num;
System.out.println("sum="+sum);//每村一次,打印金额的变化
}
}
}
class Customer implements Runnable
{
private Bank b = new Bank();
public void run()
{
for(int x=0;x<3;x++)
{
b.add(100); //一次存100
}
}
}
class ThreadDemo3
{
public static void main(String[] args)
{
Customer c = new Customer();
Thread t1 = new Thread(c);
Thread t2 = new Thread(c);
t1.start();
t2.start();
}
}
运行结果