• Java第十次作业


    (一)学习总结

    1.用思维导图对java多线程的学习内容进行总结。

    2.下面是一个单线程实现的龟兔赛跑游戏。

    public class TortoiseHareRace {
        public static void main(String[] args) {
            int totalStep = 10;
            int tortoiseStep = 0;
            int hareStep = 0;
            boolean[] flags = {true,false};
            System.out.println("龟兔赛跑开始了...");
            while(tortoiseStep < totalStep && hareStep < totalStep){
                tortoiseStep++;
                System.out.println("乌龟跑了"+tortoiseStep+"步...");
                boolean isHareSleep = flags[((int)(Math.random()*10))%2];
                if(isHareSleep){
                    System.out.println("兔子睡着了zzzz");
                }else{
                    hareStep += 2;
                    System.out.println("兔子跑了"+hareStep+"步...");
                }
            }       
        }
    }
    

    阅读程序,采用实现Runnable接口的方式用多线程实现这个小游戏。下面给出主线程类,补充Tortoise线程类和Hare线程类。

    public class TortoiseHareRace { 
        public static void main(String[] args) {
            Tortoise tortoise = new Tortoise(10);
            Hare hare = new Hare(10);
            Thread tortoiseThread = new Thread(tortoise);
            Thread hareThread = new Thread(hare);
            tortoiseThread.start();
            hareThread.start();
        }
    }
    class Tortoise implements Runnable{
    	private int totalStep;
        private int tortoiseStep;
    	public Tortoise(int totalStep) {
    		this.totalStep=totalStep;
    		this.tortoiseStep=0;
    	}
    	public void run() {
    		while(tortoiseStep < totalStep){
    			tortoiseStep++;
    			System.out.println("乌龟走了"+tortoiseStep+"步...");
    		}
    	}
    
    }
    class Hare implements Runnable{
    	private int totalStep;
        private int hareStep;
    	public Hare(int totalStep) {
    		this.totalStep=totalStep;
    		this.hareStep=0;
    	}
    	public void run() {
    		while(hareStep<totalStep){
    			boolean[] flags = {true,false};
    			boolean isHareSleep = flags[((int)(Math.random()*10))%2];
    			if(isHareSleep){
    	            System.out.println("兔子睡着了zzzz");
    	        }else{
    	            hareStep += 2;
    	            System.out.println("兔子跑了"+hareStep+"步...");
    	        }
    		}
    	}
    
    }
    

    3.下面的程序是模拟了生产者——消费者问题,生产者生产10个数,消费者依次消费10个数,运行程序,看结果是否正常?存在什么问题?说明原因。使用synchronized, wait, notify解决程序出现的问题。写出修改的部分程序即可。

    class Consumer implements Runnable {
        private Clerk clerk;
        public Consumer(Clerk clerk) {
            this.clerk = clerk;
        }
        public void run() {
            System.out.println("消费者开始消耗整数......");
            // 消耗10个整数
            for(int i = 1; i <= 10; i++) {
                try {
                     // 等待随机时间
                    Thread.sleep((int) (Math.random() * 3000));
                }
                catch(InterruptedException e) {
                    e.printStackTrace();
                }              
                clerk.getProduct();// 从店员处取走整数
            }
        }
     }
    class Producer implements Runnable {
        private Clerk clerk;
        public Producer(Clerk clerk) {
            this.clerk = clerk;
        }
        public void run() {
            System.out.println( "生产者开始生产整数......");
            // 生产1到10的整数
            for(int product = 1; product <= 10; product++) {
                try {
                    Thread.sleep((int) Math.random() * 3000);
                }
                catch(InterruptedException e) {
                    e.printStackTrace();
                }
               clerk.setProduct(product); // 将产品交给店员
            }
        } 
    }
    public class ProductTest {
        public static void main(String[] args) {
            Clerk clerk = new Clerk();
            Thread consumerThread = new Thread(new Consumer(clerk)); 
            Thread producerThread = new Thread(new Producer(clerk)); 
            consumerThread.start(); 
            producerThread.start(); 
        }
    }
    class Clerk {
        private int product = -1; // -1 表示目前没有产品 
         // 这个方法由生产者呼叫
        public void setProduct(int product) {
            this.product = product; 
            System.out.printf("生产者设定 (%d)%n", this.product);      
        } 
        // 这个方法由消费者呼叫
        public int getProduct() {          
            int p = this.product; 
            System.out.printf("消费者取走 (%d)%n", this.product);      
            return p; 
        } 
    }
    

    运行结果:
    消费者开始消耗整数......
    生产者开始生产整数......
    生产者设定 (1)
    生产者设定 (2)
    生产者设定 (3)
    生产者设定 (4)
    生产者设定 (5)
    生产者设定 (6)
    生产者设定 (7)
    生产者设定 (8)
    生产者设定 (9)
    生产者设定 (10)
    消费者取走 (10)
    消费者取走 (10)
    消费者取走 (10)
    消费者取走 (10)
    消费者取走 (10)
    消费者取走 (10)
    消费者取走 (10)
    消费者取走 (10)
    消费者取走 (10)
    消费者取走 (10)

    修改后的代码:

    class Consumer implements Runnable {
        private Clerk clerk;
        public Consumer(Clerk clerk) {
            this.clerk = clerk;
        }
        public void run() {
            System.out.println("消费者开始消耗整数......");
            // 消耗10个整数
            for(int i = 1; i <= 10; i++) {
                try {
                     // 等待随机时间
                    Thread.sleep((int) (Math.random() * 3000));
                }
                catch(InterruptedException e) {
                    e.printStackTrace();
                }              
                clerk.getProduct();// 从店员处取走整数
            }
        }
     }
    class Producer implements Runnable {
        private Clerk clerk;
        public Producer(Clerk clerk) {
            this.clerk = clerk;
        }
        public void run() {
            System.out.println( "生产者开始生产整数......");
            // 生产1到10的整数
            for(int product = 1; product <= 10; product++) {
                try {
                    Thread.sleep((int) Math.random() * 3000);
                }
                catch(InterruptedException e) {
                    e.printStackTrace();
                }
               clerk.setProduct(product); // 将产品交给店员
            }
        } 
    }
    public class Test {
        public static void main(String[] args) {
            Clerk clerk = new Clerk();
            Thread consumerThread = new Thread(new Consumer(clerk)); 
            Thread producerThread = new Thread(new Producer(clerk)); 
            consumerThread.start(); 
            producerThread.start(); 
        }
    }
    class Clerk {
        private int product = -1; // -1 表示目前没有产品
        private boolean flag=true;
         // 这个方法由生产者呼叫
        public void setProduct(int product) {
        	synchronized (this){
        		while(this.flag == false){
                    try {
                            wait();
                    } catch (InterruptedException e) {  
                    	e.printStackTrace();  
                    }
                 }
        		this.product = product; 
        		System.out.printf("生产者设定 (%d)%n", this.product);
        		this.flag = false;
        		notify();
        	}
        } 
        // 这个方法由消费者呼叫
        public int getProduct() {   
        	synchronized (this){
        		while(this.flag == true){
                    try {
                        wait();
                    } catch (InterruptedException e) {   
                    	e.printStackTrace();  
                    }
               }
               this.flag = true;
               notify();
        	   int p = this.product; 
        	   System.out.printf("消费者取走 (%d)%n", this.product);      
        	   return p; 
        	}
        } 
    }
    

    4.其他需要总结的内容。
    线程的创建
    class 类名称 extends Thread{
    属性定义;
    方法定义;
    public void run(){
    线程主体
    }
    }
    创建线程对象之后,调用start方法启动线程,自动执行run方法

    实现Runnable接口实现多线程
    例:MyThread myThread1=new MyThread();
    Thread t1 = new Thread(myThread1);
    Runnable接口只有一个run()方法,要获取线程的名字使用Thread.currentThread()

    无论使用哪种方式创建线程,都需要调用Thread中的start方法启动线程

    中断线程方法:interrupt()
    线程让步:yield()
    线程插队:join()
    延迟:sleep()

    同步方法:使用synchronized关键字将一个方法声明成同步方法

    Object类中提供了三个协调线程运行进度的方法:[wait(),notify(),(只能在同步方法中调用)],notifyAll()

    同步与死锁
    同步:多个操作在同一时间段内只能有一个线程执行,其他线程要等这个线程执行完才能继续执行
    两种方法: 一:同步代码块 二:同步方法

    注意:资源共享时需要进行同步操作 程序中过多的同步会产生死锁

    (二)实验总结

    实验内容:
    1.模拟三个老师同时分发80分作业,每个老师相当于一个线程。
    程序设计思路:定义分发作业类实现Runnable接口,在Test类中定义一个分发对象,三个线程实现三个老师分发作业的机制
    2.模拟一个银行存款的程序。假设有两个储户都去银行往同一个账户进行存款,一次存100,每人存三次。要求储户每存一次钱,账户余额增加100,并在控制台输出当前账户的余额。
    程序设计思路:定义一个银行类,设置存储方法,定义一个储户类,定义一个银行对象,使用synchronized关键字同步存储。在测试类中定义两个用户完成三次存款。

    (三)代码托管

    链接:https://git.oschina.net/hebau_cs15/javacs02sqrrr.git
    截图:

  • 相关阅读:
    JAVA中对Cookie的操作
    springboot 快速开发的定制补充
    centos7 安装 mysql5.7 版本(全)
    springboot redis-cache 自动刷新缓存
    spring-data-redis-cache 使用及源码走读
    Redis 相关功能和实用命令(五)
    Redis 集群(三)
    Redis 主从,哨兵,集群实战(四)
    redis 主从复制和哨兵模式(二)
    导出 mysql 数据到 redis
  • 原文地址:https://www.cnblogs.com/namtaehyun/p/6914770.html
Copyright © 2020-2023  润新知