(一)实验目的
1、掌握JAVA中多线程的实现方法;
2、重点掌握多线程的同步与通信机制;
3、熟悉JAVA中有关多线程同步与通信的方法 ;
4、能使用多线程机制解决实际应用中的线程同步与通信问题。
(二)实验内容和步骤
1、在线售票系统
现有一个在线售票系统,总共有200张票,假设同时有5个人同时在线订票,网络传输延时为3毫秒,试编写程序模拟售票过程。要求分别使用同步代码块与同步方法实现。
进阶设计:当有人订票的数量达到10张后则退出订票系统
💖 TicketSystem.java
public class TicketSystem
{
private int tickets = 200; // 总票数
private int bookedTickets = 0; // 已订票数
public static void main(String[] args)
{
TicketSystem ticketSystem = new TicketSystem();
ticketSystem.bookTickets();
}
// 使用同步代码块实现订票
public void bookTicketSyncBlock()
{
synchronized (this)
{
if (bookedTickets >= 10)
{
System.out.println("订票数量已达10张,订票系统退出。");
return;
}
if (tickets > 0)
{
tickets--;
bookedTickets++;
System.out.println(Thread.currentThread().getName() + "订到了一张票,剩余票数:" + tickets);
} else
{
System.out.println("票已售罄。");
}
}
}
// 使用同步方法实现订票
public synchronized boolean bookTicketSyncMethod()
{
if (bookedTickets >= 10)
{
System.out.println("订票数量已达10张,订票系统退出。");
return false;
}
if (tickets > 0)
{
tickets--;
bookedTickets++;
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次
// bookTicketSyncBlock(); // 或者使用 bookTicketSyncMethod() 来代替 bookTicketSyncBlock()
bookTicketSyncMethod();
try
{
Thread.sleep(3);// 模拟网络延迟 3 毫秒
} catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}, "Thread-" + (i + 1));
}
for (int i = 0; i < 5; i++)
threads[i].start();
}
}
💖 运行结果
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();
}
}
}
}