PS.名字什么的不重要,改成了糖果,效果是一样的。
不考虑顺序的卖票线程程序,线程不安全模式
将票改成了糖果:
public class CandyDemo {
public static void main(String[] args) throws IOException {
//读取配置文件:.properties
Properties p = new Properties();
//使用配置文件,可以随时修改配置文件从而改变数据传输
//路径中没有盘符,则默认在项目的目录下,在项目默认路径中添加文件,
//文件内容为 count=100
p.load(new FileReader("count.properties"));
//获取票数
String count = p.getProperty("count");
//将糖的数量定下来,创建代表糖的类
CandyNumber c = new CandyNumber();
//添加100颗糖
c.setCount(Integer.parseInt(count));
//创建对象,代表四个小朋友
//同时让四个小朋友看到共享的一百颗糖
Candys c1 = new Candys(c);
Candys c2 = new Candys(c);
Candys c3 = new Candys(c);
Candys c4 = new Candys(c);
//创建四个线程,代表小朋友的行为
//使用直接创建名字的构造方法,Thread类中,可以直接指定名字构造
Thread t1 = new Thread(c1, "小明");
Thread t2 = new Thread(c2, "小刚");
Thread t3 = new Thread(c3, "小华");
Thread t4 = new Thread(c4, "小萌");
//开启线程,活动开始
t1.start();
t2.start();
t3.start();
t4.start();
}
}
class Candys implements Runnable {
//由于糖果总共只有一百颗,所以需要将总数定义为公共使用数据,让所有人公用这个数据
//但是由于要共享数据,又要频繁改值,并且线程执行没有顺序,
// 所以static,会限定类的使用次数,每一次新建的类,调用的线程,都会使用static的数值,影响灵活性。
//static int candy=100; //无法优质的解决抢糖的顺序问题,所以放弃这个
//所以引入一个引用类型,来保证少糖的顺序
//注入CandyNumberd的类来当做属性,实现静态共享
CandyNumber candy;
//使用有参构造,来完成属性的赋值
//只要给定的参数一样,则能保证每个线程创建的对象中的CandyNumber属性是一样的
//由于类的对象是传地址,所以当传入参数相同的时候,就能保证他们使用的都是同一个candy
public Candys(CandyNumber cnady) {
this.candy = cnady;
}
@Override
public void run() {
//如果糖没有抢完,就继续活动
boolean isCandy=true;
while (isCandy) {
//使用同步代码块锁,锁住核心代码块,在一个时间内,要执行完当前区域代码,才能释放CPU
//synchronized (锁对象)
//锁对象,就是指定程共享的锁对象,被共享的对象就会在执行锁住代码区域中不会被抢占
//这个程序中一百个糖果是共享数据,所以要锁定糖果对象candy
synchronized (candy) {
//如果已经没有糖了,则放弃循环,直接结束活动
if (candy.getCount() == 0) {
System.out.println("糖抢完了,活动结束,请左上角关注+1");
//糖抢完了,则跳出循环
isCandy=false;
break;
}
//抢走一颗糖,就糖减一
candy.setCount(candy.getCount() - 1);
//通告谁拿到了糖,还剩多少糖
//使用Thread.currentThread()--放回当前正在执行的线程
//使用getName()方法来返回线程名称
System.out.println(Thread.currentThread().getName()
+ "抢到了糖,还剩" + candy.getCount() + "颗糖……");
}
}
}
}
class CandyNumber {
//代表糖的数量
private int count;
//由于要改变,所以提供方法
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
}
运行结果: