浅析线程同步案例

案例:火车站目前正在出售车票,共有100张票,而它有3个售票窗口售票,
请设计一个程序模拟该火车站售票。

解答:

  • 分析:三个窗口共享同一个份代码,同一份资源,但是都是独立执行,可利用实现Runnable接口的方法,但存在线程安全问题,所以主要应该解决线程安全问题
    PS:
    (1.)实现接口方式的好处:
    1.可以避免由于Java单继承带来的局限性。
    2.适合多个相同程序的代码去处理同一个资源的情况,把线程同程序的代码,数据有效分离
    (2.)产生线程安全的因素
    多线程环境下,至少有两条以上的原子性语句操作了共享数据,并且这个操作是写操作,肯定会出现线程安全问题
    下面利用三种方式解决这一问题:
  1. 同步代码块:
    格式:
    synchronized(锁对象){需要同步的代码;}
  • 注意:
    a.锁对象是任意对象
    b.不同线程共享同一把锁
    c.如果方法是静态方法,锁对象是字节码文件对象
  • 同步的好处
    解决了多线程的安全问题。
  • 同步的弊端
    当线程相当多时,因为每个线程都会去判断同步上的锁,这是很耗费资源的,
    降低程序的运行效率。如果出现了同步嵌套,就容易产生死锁问题
public class Test4 {
	public static void main(String[] args) {
		SaleTicketsThread st = new SaleTicketsThread();
		Thread stt = new Thread(st,"窗口一");
		Thread stt2 = new Thread(st,"窗口二");
		Thread stt3 = new Thread(st,"窗口三");
		stt.start();
		stt2.start();
		stt3.start();		
	}
}
class SaleTicketsThread implements Runnable{
	public int tickets = 100;
	@Override
	public void run() {
		while (true) {
		synchronized (MyLock.LOCK) {
				if (tickets>0) {
					try {
						Thread.sleep(50);//设置线程休眠时间
					} catch (InterruptedException e) {
					e.printStackTrace();
					}
					System.out.println(Thread.currentThread().getName()+"正在售第"+tickets--+"张票");
					Thread.yield();
				}
			}
		}		
}
//自定义锁对象
class MyLock {
	public static final Object LOCK = new Object();	
}

2.同步方法
格式:
public synchronized 返回值 方法名(参数列表) {
//需要同步的代码块
}
注意:
a.同步方法的锁对象是 this

public class Test4 {
	public static void main(String[] args) {
		SaleTicketsThread st = new SaleTicketsThread();
		Thread stt = new Thread(st,"窗口一");
		Thread stt2 = new Thread(st,"窗口二");
		Thread stt3 = new Thread(st,"窗口三");
		stt.start();
		stt2.start();
		stt3.start();		
	}
}
class SaleTicketsThread implements Runnable{
	public int tickets = 100;
	@Override
	public void run() {
		while (true) {
			sellTicket();
		}		
	}
public synchronized void sellTicket() {
		if (tickets>0) {
			try {
				Thread.sleep(50);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName()+"正在售第"+tickets--+"张票");			
		}
	}
}

3.Lock锁 (系统提供)

public class Test4 {
	public static void main(String[] args) {
		SaleTicketsThread st = new SaleTicketsThread();
		Thread stt = new Thread(st,"窗口一");
		Thread stt2 = new Thread(st,"窗口二");
		Thread stt3 = new Thread(st,"窗口三");
		stt.start();
		stt2.start();
		stt3.start();		
	}
}
class SaleTicketsThread implements Runnable{
	public int tickets = 100;
	Lock lock = new ReentrantLock();
	@Override
	public void run() {
		while (true) {
			lock.lock();
			if (tickets > 0) {
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				System.out.println(Thread.currentThread().getName() + "正在出售第" + (tickets --) + "张票");
				
			}
			lock.unlock();
		}		
	}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值