(一)实验目的
1、掌握JAVA中多线程的实现方法;
2、重点掌握多线程的同步与通信机制;
3、熟悉JAVA中有关多线程同步与通信的方法 ;
4、能使用多线程机制解决实际应用中的线程同步与通信问题。
(二)实验内容和步骤
1、现有一个在线售票系统,总共有200张票,假设同时有5个人同时在线订票,网络传输延时为3毫秒,试编写程序模拟售票过程。要求分别使用同步代码块与同步方法实现。
进阶设计:当有人订票的数量达到10张后则退出订票系统
SellingSystem1.java
package OnlineTicketingSystem;public class SellingSystem1 implements Runnable{//定义200张票private static int tickets = 200;//锁对象private static Object obj = new Object();@Overridepublic void run() {for(int i=0; i<10; i++) { //每个进程各买10张
// bookTicket1();bookTicket2();if(i == 9) //某个线程达到10张票{System.out.println("订票系统关闭");System.exit(0); //return 0}try {Thread.sleep(3);} catch (InterruptedException e) {e.printStackTrace();}}}public void bookTicket1() //同步代码块{synchronized (obj) {if (tickets > 0) {//网络延迟3毫秒System.out.println(Thread.currentThread().getName() + "正在购买第" + (tickets--) + "张票");}} }public synchronized void bookTicket2() //同步方法{if(tickets > 0) {//网络延迟3毫秒System.out.println(Thread.currentThread().getName() + "正在购买第" + (tickets--) + "张票"); } }
}
SystemMain.java
package OnlineTicketingSystem;public class SystemMain {public static void main(String[] args) {// 创建资源对象SellingSystem1 sellingsystem1 = new SellingSystem1(); // 创建三个线程对象Thread thread1 = new Thread(sellingsystem1, "用户1");Thread thread2 = new Thread(sellingsystem1, "用户2");Thread thread3 = new Thread(sellingsystem1, "用户3");Thread thread4 = new Thread(sellingsystem1, "用户4");Thread thread5 = new Thread(sellingsystem1, "用户5");thread1.start(); thread2.start();thread3.start(); thread4.start();thread5.start();}
}
【运行结果】
2、坦克大战游戏
在坦克大战游戏当中,我方坦克和敌方坦克均可以发射炮弹。现只考虑我方坦克发射炮弹的情况,在没有升级前,我方坦克发射的炮弹只有在碰到敌方坦克、障碍物爆炸或越过边界后(可以使用线程休眠一定时间来模拟)才能发射下一发炮弹。请编写程序模拟我方坦克发射炮弹的过程。
package TankWar;import java.util.Timer;
import java.util.TimerTask;class MyTank extends TimerTask{public int x = 0;@Overridepublic void run() {System.out.print("我方坦克发射炮弹碰到");if(x % 3 == 0)System.out.println("障碍物");else if(x % 2 == 0)System.out.println("日本鬼子的坦克");elseSystem.out.println("越过边界");x++;}
}public class Game {public static void main(String[] args) {Timer t = new Timer();//炮弹3秒爆炸,循环发射t.schedule(new MyTank(), 3000, 3000);}
}
【运行结果】
存在的问题:线程之间没有竞争
解决办法:要想竞争,就要有休眠。问题就出现在这里。把休眠代码块放出来即可,不能放在锁对象框住的代码块里面,否则就会变成一个人买10张的情况:
存在的问题:当有人达到10张票就关闭系统,上述图片每个人都买10张。只有1人拥有10张,其他人小于9张
解决办法:用一个循环,循环10次买票方法,当前线程已经循环10次就结束程序