GDPU Java 天码行空12 线程同步与通信

(一)实验目的

1、掌握JAVA中多线程的实现方法;
2、重点掌握多线程的同步与通信机制;
3、熟悉JAVA中有关多线程同步与通信的方法 ;
4、能使用多线程机制解决实际应用中的线程同步与通信问题。

(二)实验内容和步骤

1、在线售票系统

现有一个在线售票系统,总共有200张票,假设同时有5个人同时在线订票,网络传输延时为3毫秒,试编写程序模拟售票过程。要求分别使用 同步代码块同步方法 实现。

进阶设计:当有人订票的数量达到10张后则退出订票系统

💖 TicketSystem.java

public class TicketSystem
{
	private volatile int tickets = 200; // 总票数
	private volatile boolean finished = false;

	public static void main(String[] args)
	{
		TicketSystem ticketSystem = new TicketSystem();
		ticketSystem.bookTickets();
	}

	// 使用同步代码块实现订票
	public void bookTicketSyncBlock()
	{
		synchronized (this)
		{
			if (finished)
				return;
			if (tickets > 0)
			{
				tickets--;
				System.out.println(Thread.currentThread().getName() + "订到了一张票,剩余票数:" + tickets);
			} else
			{
				System.out.println("票已售罄。");
			}
		}
	}

	// 使用同步方法实现订票
	public synchronized boolean bookTicketSyncMethod()
	{
		if (finished)
			return false;
		if (tickets > 0)
		{
			tickets--;
			System.out.println(Thread.currentThread().getName() + "订到了一张票,剩余票数:" + tickets);
			return true;
		} else
		{
			System.out.println("票已售罄");
			return false;
		}
	}

	// 模拟订票过程
	public void bookTickets()
	{
		Thread[] threads = new Thread[5];
		for (int i = 0; i < threads.length; i++)
		{
			threads[i] = new Thread(() -> {
				for (int j = 0; j < 10; j++)
				{ // 每个线程尝试订票10次
					synchronized (this)
					{
						bookTicketSyncBlock(); // 或者使用 bookTicketSyncMethod() 来代替 bookTicketSyncBlock()
//						bookTicketSyncMethod();
						if (j == 9)// 某个线程抢到了 10 张票,购票系统关闭
							finished = true;
					}
					try
					{
						Thread.sleep(30);// 模拟网络延迟 3 毫秒
					} catch (InterruptedException e)
					{
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}, "Thread-" + (i + 1));
		}
		for (int i = 0; i < 5; i++)
			threads[i].start();

	}
}

💖 运行结果

Thread-1订到了一张票,剩余票数:199
Thread-5订到了一张票,剩余票数:198
Thread-4订到了一张票,剩余票数:197
Thread-3订到了一张票,剩余票数:196
Thread-2订到了一张票,剩余票数:195
Thread-5订到了一张票,剩余票数:194
Thread-2订到了一张票,剩余票数:193
Thread-1订到了一张票,剩余票数:192
Thread-3订到了一张票,剩余票数:191
Thread-4订到了一张票,剩余票数:190
Thread-2订到了一张票,剩余票数:189
Thread-5订到了一张票,剩余票数:188
Thread-4订到了一张票,剩余票数:187
Thread-1订到了一张票,剩余票数:186
Thread-3订到了一张票,剩余票数:185
Thread-4订到了一张票,剩余票数:184
Thread-1订到了一张票,剩余票数:183
Thread-3订到了一张票,剩余票数:182
Thread-2订到了一张票,剩余票数:181
Thread-5订到了一张票,剩余票数:180
Thread-5订到了一张票,剩余票数:179
Thread-3订到了一张票,剩余票数:178
Thread-1订到了一张票,剩余票数:177
Thread-2订到了一张票,剩余票数:176
Thread-4订到了一张票,剩余票数:175
Thread-4订到了一张票,剩余票数:174
Thread-3订到了一张票,剩余票数:173
Thread-5订到了一张票,剩余票数:172
Thread-1订到了一张票,剩余票数:171
Thread-2订到了一张票,剩余票数:170
Thread-5订到了一张票,剩余票数:169
Thread-2订到了一张票,剩余票数:168
Thread-4订到了一张票,剩余票数:167
Thread-1订到了一张票,剩余票数:166
Thread-3订到了一张票,剩余票数:165
Thread-1订到了一张票,剩余票数:164
Thread-5订到了一张票,剩余票数:163
Thread-4订到了一张票,剩余票数:162
Thread-2订到了一张票,剩余票数:161
Thread-3订到了一张票,剩余票数:160
Thread-2订到了一张票,剩余票数:159
Thread-3订到了一张票,剩余票数:158
Thread-4订到了一张票,剩余票数:157
Thread-5订到了一张票,剩余票数:156
Thread-1订到了一张票,剩余票数:155
Thread-1订到了一张票,剩余票数:154

2、坦克大战

在坦克大战游戏当中,我方坦克和敌方坦克均可以发射炮弹。现只考虑我方坦克发射炮弹的情况,在没有升级前,我方坦克发射的炮弹只有在碰到敌方坦克、障碍物爆炸或越过边界后(可以使用线程休眠一定时间来模拟)才能发射下一发炮弹。请编写程序模拟我方坦克发射炮弹的过程。

💖 Game.java

public class Game
{
	public static void main(String[] args)
	{
		Tank friendlyTank = new Tank("我方坦克");
		// 模拟我方坦克连续发射炮弹
		for (int i = 0; i < 5; i++)
		{
			friendlyTank.fireBullet();
			try
			{
				Thread.sleep(5000); // 模拟炮弹发射间隔时间
			} catch (InterruptedException e)
			{
				e.printStackTrace();
			}
		}
	}

	static class Tank
	{
		private String name;

		public Tank(String name)
		{
			this.name = name;
		}

		public void fireBullet()
		{
			System.out.println(name + " 发射了一发炮弹!");
			new Bullet(this).start(); // 创建一个线程来模拟炮弹的移动
		}
	}

	static class Bullet extends Thread
	{
		private Tank tank;

		public Bullet(Tank tank)
		{
			this.tank = tank;
		}

		@Override
		public void run()
		{
			try
			{
				// 模拟炮弹飞行时间
				Thread.sleep(2000); // 假设炮弹飞行2秒
				System.out.println(tank.name + " 的炮弹飞行了2秒后爆炸了!");
			} catch (InterruptedException e)
			{
				e.printStackTrace();
			}
		}
	}
}

💖 运行结果

在这里插入图片描述

  • 14
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值