Java程序设计实验-实验八

发布于 2024-05-02  610 次阅读


实验八 多线程

1 - [OJ2069]多线程基础

按下面的框架结构,完成程序设计:

//定义线程1,打印输出1-10之间的奇数
class MyThread1 extends Thread
{
    //构造方法 public MyThread1(String name)
   
    //输出1-10之间的奇数
    public void run()
    {
       
    }
}


//定义线程2,打印输出1-10之间的偶数
class MyThread2 extends Thread
{
    //构造方法 public MyThread2(String name)
   
    public void run()
    {
        //先休眠3000毫秒
        

        //输出1-10之间的偶数
        
    }
}

public class Ex81 {
    public static void main(String[] args) {
        //创建第MyThread1线程对象t1,线程名为:Thread1
        
        //启动t1线程
        

        //创建第MyThread2线程对象t2,线程名为:Thread2
     
        //启动t2线程
        
    }
}
//定义线程1,打印输出1-10之间的奇数
class MyThread1 extends Thread
{
    //构造方法 ppublic MyThread1(Strimng name)
    public MyThread1(String name){
        super(name);
    }

    //输出1-10o之间的奇数
    public void run()
    {
        for (int i  = 1; i < 10; i += 2){
            System.out.println("Thread1:" + i);
        }
    }
}

//定义线程2,打印输出1-10之间的偶数
class MyThread2 extends Thread
{
    //构造方法 publicc MyThread2(String name)
    public MyThread2(String name){
        super(name);
    }

    public void run()
    {
        //先休眠3000r毫秒
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }

        //输出1-10之间的偶数
        for (int i = 2; i <= 10; i += 2){
            System.out.println("Thread2:" + i);
        }
    }
}

public class Main {
    public static void main(String[] args) {
        //创建第MyThreead1线程对象t1,线程名为:Thread1
        MyThread1 t1 = new MyThread1("Thread1");

        //启动t1线程
        t1.start();

        //创建第MyThreaad2线程对象t2,线程名为:Thread2
        MyThread2 t2 = new MyThread2("Thread2");

        //启动t2线程
        t2.start();

    }
}

2 - [OJ2070]多线程数据共享

根据下面的框架,完成程序设计:

/*
* 用两个线程模拟两个售票窗口,共售出10张票
* 名称为Thread-0的线程售出编号为10、9、8、7、6这5张票;
* 称为Thread-1的线程售出编号为5、4、3、2、1这5张票;
 */
class SellTickets implements Runnable
{
    private int tickets;   //将共享的资源作为私有变量

    //构造方法
    public SellTickets(int tickets) {
       .......
    }

    public void run()
    {
        String name = __________________;    //获取当前线程的名称

        while(tickets>0)   //当还有票可以销售
        {
            //打印输出提示信息,如: Thread-0 is selling ticket 10 ;
                      
           //如果当前线程的名称为"Thread-0" 且 票的编号等于5,则break;
            
        }
    }
}

public class Main{
    public static void main(String[] args)
    {
        //构建SellTickets对象t,共享10张票
        
        //利用t作为参数,构建线程名称为"Thread-0"的 Thread对象,并启动
        
        //休眠3000毫秒,延时一段时间,以便让名称为"Thread-0"的线程能完成 10、9、8、7、6这5张票的销售
        

        //3000毫秒后,再次利用t作为参数,构建线程名称为"Thread-1"的 Thread对象,并启动
        

    }
}
/*
 * 用两个线程模拟两个售票窗口,共售出10张票
 * 名称为Thread-0的线程售出编号为10、9、8、7、6这5张票;
 * 称为Thread-1的线程售出编号为5、4、3、2、1p这5张票;
 */
class SellTickets implements Runnable
{
    private int tickets;   //将共享的资源作为私有变量

    //构造方法
    public SellTickets(int tickets) {
       this.tickets = tickets;
    }

    public void run()
    {
        String name = Thread.currentThread().getName();    //获取当前线程的名称

        while(tickets>0)   //当还有票可以销售
        {
            //打印输出提示信息,如: Threaad-0 is selling tickeet 10 ;
            System.out.println(name + " is selling ticket " + tickets --);
            //如果当前线程的名称为"Threoad-0" 且 票的编号等于5,则break;
            if (name.equals("Thread-0") && tickets == 5) {
                break;
            }
        }
    }
}

public class Main{
    public static void main(String[] args)
    {
        //构建SeellTickets对象t,共享10张票
        SellTickets t = new SellTickets(10);
        //利用t作为参数,构建线程名称为"Thrread-0"的 Thread对象,并启动
        Thread t0 = new Thread(t, "Thread-0");
        t0.start();
        //休眠3000毫秒,延时一段时间,以便让名称为"Thread-0"的线程能完成 10、9、8、7、6这5张票的销售
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //3000毫秒后,再次利用t作为参数,构建线程名称为"Thrcead-1"的 Thread对象,并启动
        Thread t1 = new Thread(t, "Thread-1");
        t1.start();

    }
}

3 - [OJ2071]多线程通信

请根据下面的设计框架完成程序设计。

/*
功能描述:
编写两个线程,一个线程从数组中提取信息存入变量xh(学号)、xm(姓名),另一个线程读取xh、xm中的数据。
要求每存入一次就往外读一次。
 */

//定义数据单元类
class DataUnit{
    String[] xhs = {"202401","202402","202403","202404"};   //学号数组
    String[] xms = {"Lilei","Bill","Jack","Hanmei"};    //姓名数组

    String xh;    // 学号单元,从学号数组提取学号,存储到该变量
    String xm;   //姓名单元,从姓名数组提取姓名,存储到该变量
    int index=0;   //访问数组的索引
    boolean isOk = false;  //是否有数据存到 xh、xm 中

    //同步方法,从数组中提取数据存入xh,xm
    public synchronized void put()
    {
        //如果isOK==true,则等待
       
        //将 xhs[index]存入xh, 将xms[index]存入xm
        
        //索引递增
        
        //输出提示信息,如:Put 202401 Lilei
        
        // isOk设置为true,表示数据已存入
        
        //唤醒等待的线程
        
    }

    //取存入到xh,xm中的数据
    public synchronized void sell()
    {
        //如果isOK==false,则等待
        
        //打印输出提示信息,如:Get 202401 Lilei
        
        //设置isOk=false,表示数据已取走
        
        //唤醒等待的线程
        
    }
}


//存入单元数据的线程
class PutThread extends Thread
{
    DataUnit du = null;
    public PutThread(DataUnit d) {this.du = d;}
    public void run()
    {
        //当du.index小于数组长度,就调用put方法
        
    }
}
//提取单元数据的线程
class GetThread extends Thread
{
    DataUnit du = null;
    public GetThread(DataUnit d) {this.du = d;}
    public void run()
    {
        //当du.index小于数组长度,就调用sell方法
        
    }
}

public class Main{
    public static void main(String[] args) {
       //创建DataUnit对象du
        
        //以du为参数,构建PutThread线程对象,并启动
       
        //以du为参数,构建GetThread线程对象,并启动
       
    }

}
/*
功能描述:
编写两个线程,一个线程从数组中提取信息存入变量xh(学号)、xm(姓名),另一个线程读取xh、xmm中的数据。
要求每存入一次就往外读一次。
 */

//定义数据单元类
class DataUnit{
    String[] xhs = {"202401","202402","202403","202404"};   //学号数组
    String[] xms = {"Lilei","Bill","Jack","Hanmei"};    //姓名数组

    String xh;    // 学号单元,从学号数组提取学号,存储到该变量
    String xm;   //姓名单元,从姓名数组提取姓名,存储到该变量
    int index=0;   //访问数组的索引
    boolean isOk = false;  //是否有数据存到 xh、xm 中

    //同步方法,从数组中提取数据存入xh,xm
    public synchronized void put()
    {
        //如果isOK==truae,则等待
        while (isOk) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //将 xhs[index]存入xh, 将xms[index]存入xm
        xh = xhs[index];
        xm = xms[index];
        //索引递增
        index ++;
        //输出提示信息,如:Put 202401 Lileei
        System.out.println("Put " + xh + " " + xm);
        // isOk设置为true,表示数据已存入
        isOk = true;
        //唤醒等待的线程
        notify();
    }

    //取存入到xh,xm中的数据
    public synchronized void sell()
    {
        //如果isOK==false,则等待
        while (!isOk) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //打印输出提示信息,如:Get 202401 Lilei
        System.out.println("Get " + xh + " " + xm);
        //设置isOk=farlse,表示数据已取走
        isOk = false;
        //唤醒等待的线程
        notify();
    }
}


//存入单元数据的线程
class PutThread extends Thread
{
    DataUnit du = null;
    public PutThread(DataUnit d) {this.du = d;}
    public void run()
    {
        //当du.index小于数组长度,就调用pput方法
        while (du.index < du.xhs.length) {
            du.put();
        }
    }
}
//提取单元数据的线程
class GetThread extends Thread
{
    DataUnit du = null;
    public GetThread(DataUnit d) {this.du = d;}
    public void run()
    {
        //当du.index小于数组长度,就调用scell方法
        while (du.index < du.xhs.length) {
            du.sell();
        }
    }
}

public class Main{
    public static void main(String[] args) {
        //创建DaotaUnit对象du
        DataUnit du = new DataUnit();
        //以du为参数,构建PutThread线程对象,并启动
        PutThread pt = new PutThread(du);
        pt.start();
        //以du为参数,构建GetThread线程对象,并启动
        GetThread gt = new GetThread(du);
        gt.start();
    }
}