package day10;
/**
* 多线程并发访问同一资源时,就会形成"抢"的现象。
* 由于线程切换时机不确定,可能会导致执行代码顺序的混乱,严重时会导致系统瘫痪。
*
* 实例:模拟两个人(两个线程)同时从一个桌子上拿豆子,考察并发出错情况。
* @author kaixu
*
*/
public class SyncDemo1 {
public static void main(String[] args) {
final Table table = new Table();
Thread t1 = new Thread(){
public void run(){
while(true){
int bean = table.getBeans();
Thread.yield(); //增加并发出错几率,主动出让CPU时间
System.out.println(getName()+":"+bean);
}
}
};
Thread t2 = new Thread(){
public void run(){
while(true){
int bean = table.getBeans();
Thread.yield(); //增加并发出错几率,主动出让CPU时间
System.out.println(getName()+":"+bean);
/* 出错时输出:
* Thread-1:-299283
Thread-0:-299284
Thread-1:-299285
Thread-0:-299286
...
*/
}
}
};
t1.start();
t2.start();
}
}
class Table{
//桌子上有20个豆子
private int beans = 20;
public int getBeans(){
/*
* 加锁以后可以控制单线程访问方法,解决异常并发。
* 当一个方法被synchronized修饰后,该方法为同步方法
* 即:多个线程不能同时进入方法内部执行。
* 对于成员方法而言,synchronized会在一个线程调用该方法是将该方法
* 所属的对象加锁。其他线程在执行该方法时由于执行方法的线程没有释放锁,
* 所以只能在方法外阻塞,直到持有方法锁的线程将方法执行完毕。所以,解决
* 多线程并发执行安全问题的办法就是将"抢"变为"排队"。
* public synchronized int getBeans(){...}
*/
if(beans==0){
throw new RuntimeException("没有豆子了!");
}
Thread.yield(); //模拟线程出错
return beans--;
}
}
Java实例模拟多线程并发的出错状态
最新推荐文章于 2025-03-12 13:59:53 发布