(一)实验目的
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();
    @Override
    public 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;
	@Override
	public void run() {
		System.out.print("我方坦克发射炮弹碰到");
		if(x % 3 == 0)
			System.out.println("障碍物");
		else if(x % 2 == 0)
			System.out.println("日本鬼子的坦克");
		else
			System.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次就结束程序



















