Java程序设计实验四 多线程程序设计

[1]实验目的理解多线程的概念,掌握创建、管理和控制Java线程对象的方法,包括创建Java线程对象、改变线程状态、设置线程优先级及控制线程调度等方法,掌握实现线程互斥和线程同步的方法。

[2]实验内容:

1、编写一个有两个线程的程序,第一个线程用来计算1~100之间的偶数及个数,第二个线程用来计算1-100之间的偶数及个数。

package experiment4;
class NumberRunnable implements Runnable{
    private final int first;
    NumberRunnable(int first){
        this.first=first;
    }
    @Override
    public void run() {
        for (int i=first;i<=100;i+=2){
            System.out.println(i+ " ");
        }
        System.out.println("结束!");
    }
}
public class Exp4_1 {
    public static void main(String[] args){
        NumberRunnable runnable1 = new NumberRunnable(1);
        NumberRunnable runnable2 = new NumberRunnable(2);
        Thread thread_odd = new Thread(runnable1,"奇数线程");
        Thread thread_even = new Thread(runnable2,"偶数线程");
        thread_odd.start();
        thread_even.start();
    }
}

 

  

2、编写一个Java应用程序,在主线程中再创建两个线程,要求线程经历四种状态:新建,运行、中断和死亡。按模板要求,将【代码1】~【代码8】替换为Java程序代码。

class Tortoise extends Thread
{     int sleepTime=0, liveLength=0;
      public Tortoise(String name,int sleepTime, int liveLength)
      {      
            this.sleepTime=sleepTime;
            this.liveLength=liveLength; 
            【代码1】 // 设置线程的名字为name
      }
      public void run()
      {   while (true )
          {
              liveLength--;
	           System.out.println("@_@");
               try{  
                   【代码2】 // 让线程调用sleep()方法进入中断状态
                }
               catch (InterruptedException e) {}
                if (liveLength<=0 )
                {
                    System.out.println(getName()+"进入死亡状态\n");
	                【代码3】 // 结束run()方法的语句
                 }
             }
      }
}
class Rabit extends Thread
{
      int sleepTime=0, liveLength=0;
      public Rabit(String name,int sleepTime, int liveLength)
      {
            【代码4】 // 调用父类构造函数,设置线程的名字为name
            this.sleepTime=sleepTime;
            this.liveLength=liveLength;
      }
      public void run()
      {
             while (true )
             {
                  liveLength--;
	              System.out.println("*_*");
                 try{
                           sleep( sleepTime);
                }
               catch (InterruptedException e) {}
                if (liveLength<=0 )
                {
                     System.out.println(getName()+"进入死亡状态\n");
	                  break;
                 }
             }
      }
}
public  class ThreadExample
{
     public static void main(String a[])
    {
         Rabit rabit;
         rabit =【代码5】  // 新建线程rabit
        Tortoise tortoise =【代码6】  // 新建线程tortoise
        【代码7】  // 启动线程tortoise
        【代码8】  // 启动线程rabit
    }
}

package experiment4;
class Tortoise extends Thread
{
    int sleepTime,liveLength;
    public Tortoise(String name,int sleepTime,int liveLength)
    {
        super(name);//【代码1】设置线程的名字为name
        this.sleepTime=sleepTime;
        this.liveLength=liveLength;
    }
    public void run()
    {
        while(true)
        {
            liveLength--;
            System.out.println("@_@");
            try {
                sleep(sleepTime);//【代码2】让线程调用sleep()方法进入中断状态
            }
            catch(InterruptedException ignored) {}
            if(liveLength<=0)
            {
                System.out.println(getName()+"进入死亡状态\n");
                break;//【代码3】结束run()方法的语句
            }
        }
    }
}

class Rabbit extends Thread
{
    int sleepTime,liveLength;
    public Rabbit(String name,int sleepTime,int liveLength)
    {
        super(name);//【代码4】调用父类构造函数,设置线程的名字为name
        this.sleepTime=sleepTime;
        this.liveLength=liveLength;
    }
    public void run()
    {
        while(true)
        {
            liveLength--;
            System.out.println("*_*");
            try {
                sleep(sleepTime);
            }
            catch(InterruptedException ignored) {}
            if(liveLength<=0)
            {
                System.out.println(getName()+"进入死亡状态\n");
                break;
            }
        }
    }
}

public class Exp4_2 {
    public static void main(String[] args){
        Rabbit rabbit;
        rabbit = new Rabbit("Rabbit",200,100);
        Tortoise tortoise = new Tortoise("Tortoise", 200,100);
        rabbit.start();
        tortoise.start();
    }
}

 

 

*3、编写Java应用程序模拟5个人排队买票。售票员只有1张五元的钱,电影票五元钱一张。假设5个人的名字及排队顺序是:赵、钱、孙、李、周。“赵”拿1张二十元的人民币买2张票,“钱”拿1张二十元的人民币买1张票,“孙”1张十元的人民币买1张票,“李”拿1张十元的人民币买2张票,“周”拿1张五元的人民币买1张票。

要求售票员按如下规则找赎:

(1)二十元买1张票,找零:1张十元;不许找零2张五元。

(2)二十元买1张票,找零:1张十元,1张五元;不许找零3张五元。

(3)十元买一张票,找零1张五元。

package experiment4;

import java.util.Objects;

class BuyTickets //临界资源
{
    private static int five =1, ten =0, twenty =0;//钱的张数可以根据这个来统计 
    public synchronized void buy(int money,int count) {
        //20元买两张票
        if (money == 20 && count == 2) {
            System.out.println("赵来买票");
            twenty++;//先收下钱
            //开始不能找钱
            if(ten <1)
            {
                try {
                    System.out.println("赵稍等"+"   此时售票员手中的票为:5元有 "+ five +" ,10元有:"+ ten +" ,20元有:"+ twenty);
                    this.wait();
                } catch (InterruptedException e) {}
            }
            //之后的没有办法成功找钱,就继续进入等待状态
            while(ten <1) {
                try {
                    this.wait();
                } catch (InterruptedException e) {}
            }
            ten--;//把钱找给他
            notify();//唤醒
            System.out.println("找给赵1张10元,赵结束"+"   此时售票员手中的票为:5元有"+ five +",10元有:"+ ten +",20元有:"+ twenty);

        }
        //20元买1张票
        else if (money == 20 && count == 1) {
            twenty++;
            System.out.println("钱来买票");
            //找零:1张十元,1张五元
            if(ten <1|| five <1)
            {try {
                System.out.println("钱稍等"+"   此时售票员手中的票为:5元有 "+ five +" ,10元有:"+ ten +" ,20元有:"+ twenty);
                this.wait();
            } catch (InterruptedException e) {}
            }
            while(ten <1|| five <1) {
                try {
                    this.wait();
                } catch (InterruptedException e) {}
            }
            ten--;
            five--;
            notify();
            System.out.println("找给钱1张10元、1张5元,钱结束"+"   此时售票员手中的票为:5元有"+ five +" ,10元有:"+ ten +" ,20元有:"+ twenty
            );
        }
        //10元买1张票
        else if (money == 10 && count == 1) {
            ten++;
            System.out.println("孙来买票");
            if(five <1)
            {
                try {

                    System.out.println("孙稍等"+"   此时售票员手中的票为:5元有 "+ five +" ,10元有:"+ ten +" ,20元有:"+ twenty);
                    this.wait();
                } catch (InterruptedException e) {}
            }
            while(five <1) {
                try {
                    this.wait();
                } catch (InterruptedException e) {}
            }//没有办法成功找钱,就继续进入等待状态
            five--;
            notify();//唤醒
            System.out.println("找给孙1张5元,孙结束"+"   此时售票员手中的票为:5元有"+ five +",10元有:"+ ten +",20元有:"+ twenty);
        }
        //10元买2张票
        else if (money == 10 && count == 2) {
            ten++;
            System.out.println("李来买票");
            System.out.println("李结束"+"   此时售票员手中的票为:5元有 "+ five +" ,10元有:"+ ten +" ,20元有:"+ twenty);
            notify();
        }
        //5元买1张票
        else if (money == 5 && count == 1) {
            five++;
            System.out.println("周来买票");
            System.out.println("周结束"+"   此时售票员手中的票为:5元有 "+ five +" ,10元有:"+ ten +" ,20元有:"+ twenty);
            notify();
        }
    }
}
class customer extends Thread//继承Thread类,创建多个线程
{
    String name;
    static final BuyTickets buyTickets = new BuyTickets();

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

    public void run() {
            if (Objects.equals(name, "赵")) buyTickets.buy(20, 2);
            else if (Objects.equals(name, "钱")) buyTickets.buy(20, 1);
            else if (Objects.equals(name, "孙")) buyTickets.buy(10, 1);
            else if (Objects.equals(name, "李")) buyTickets.buy(10, 2);
            else if (Objects.equals(name, "周")) buyTickets.buy(5, 1);

    }
}

public class Exp4_3 {
    public static void main(String[] args) {
        new customer("赵").start();
        new customer("钱").start();
        new customer("孙").start();
        new customer("李").start();
        new customer("周").start();
    }
}

[3]实验分析

通过此次实验,熟悉了在Java中进行多线程编程的能力。在第三题中,由于买票的情况和找钱的情况有限,所有我将各种情况均枚举出来,作为临界区。临界资源则是售票员手里的各种钱的数量,同时这也作为各线程之间进行通信的信号量。

将五个人买票当作五个线程来进行,在临界区的方法声明中加入synchronized的关键字,实现线程互斥。

实验结果每次运行均不一样,但是都能符合实际。

  • 4
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ace2NoU

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值