zoukankan      html  css  js  c++  java
  • 201871010128-杨丽霞《面向对象程序设计(java)》第十六周学习总结

    201871010128-杨丽霞《面向对象程序设计(java)》第十六周学习总结(1分)

     

    项目

    内容

    这个作业属于哪个课程

    https://www.cnblogs.com/nwnu-daizh/

    这个作业的要求在哪里

    https://www.cnblogs.com/nwnu-daizh/p/12031970.html

    作业学习目标

    (1) 掌握Java应用程序的打包操作;

    (2) 掌握线程概念;

    (3) 掌握线程创建的两种技术。

     

     

    第一部分:总结教材14.1-14.3知识内容(20分)

     14.1什么是线程

    • 进程与线程
      1,多个进程额内部数据和状态是完全独立的,而多个线程是共享一块内存空间和一组资源,有可能互相影响;
      2,每个进程都有一段专用的内存区域,而线程间可以共享相同的内存单元,(包括代码和数据)并利用这些共享单元来实现数据交换,实时通信与必要的同步操作。
    • Java实现多线程有两种途径:

      ‐创建Thread类的子类

      ‐在程序中定义实现Runnable接口的类

    • 主线程
      每个java程序都至少有一个线程,即主线程,当一个Java程序启动时,jvm会创建主线程,并在该线程中调用程序的main()方法。
      主线程的作用是:

      1.它是产生其他子线程的线程。
      2.通常它必须最后完成执行,因为它执行各种关闭动作。
      尽管主线程在程序启动时自动创建,但它可以由一个Thread对象控制。
      eg:调用Thread.currentThread()静态方法,返回调用该方法的当前线程的引用;

    Thread th1= Thread.currentThread();System.out.println("我是主线程:"+th1.getName());

     ·  创建线程的两种方法:
    1,通过实现Runnable接口,重写其中的run()方法,再调用Thread类的构造方法Thread(Runnable,Threadname)来实现
    2,通过创建Thread类的子类来实现,即继承Thread类,重写其中的run()方法
    eg:创建一个线程,可以之定义线程名字

    class HelloThread extends Thread{String name;public HelloThread(String name) {

     super(name);}

        @Overridepublic void run() {

     }}

      Java中线程的方法
    start()通过调用本线程的run()方法,使调用该方法的线程开始执行
    run() 当一个线程初始化之后,start()方法会自动的调用run()方法,在该方法内编写运行本线程时需要执行的代码,也是Runnable接口的唯一方法,一旦run()方法返回,本线程也就终止了。(一般不再线程中直接调用此方法)
    final void join() //等待该线程结束,调用了该方法的线程拥有高于其他线程的优先级
    static void yield() //把正在执行的线程临时暂停,其实就是使当前线程放弃cpu,进入就绪状态,重新排队,所以可以允许其他线程运行
    final boolean isAlive() //返回线程是否处于活动状态

    Java多线程的优点

    1. 它不会阻塞用户,因为线程是独立的,你可以同时执行多个操作,举个栗子,你需要一个延时,等待三秒钟再进行接下来的操作,如果你使用单线程,它就真的等了你三秒,这三秒,啥都不干,啥都得放一边,就等。。。这明显是不可接受的。

    2. 你可以同时执行多个操作,节省时间。这里面又牵扯到CPU密集型和IO密集型的问题

    3. 线程是独立的,死掉一个,不影响另一个。

    14.2中断线程

    JAVA中断线程三大基本方法

    方法一

    程正常执行完毕,正常结束。也就是让run方法执行完毕,该线程就会正常结束。

    方法二

    监视某些条件,结束线程的不间断运行。然而,通常有些线程是伺服线程,它们往往需要长时间的运行,只有在外部某些条件满足的情况下,才能关闭这些线程。一般情况下,它们执行在一个while(true)的死循环中。我们可以在while死循环内,每次循环时,察看外部条件,看看是否需要关闭当前线程。如果是,就break,跳出死循环,或者是抛出异常,跳出死循环,结束线程。

    方法三

    捕获InterruptedException运行时异常,中断当前线程。有些执行伺服任务的线程,在while(true)这样的死循环内部,是一个阻塞中的方法。此时,就不能采用第二种方法了。因为,当该方法没有返回时,该线程会一直处于阻塞当中,根本无法执行其他语句。这时候就需要调用该线程的interrupt方法,产生一个InterruptedException运行时异常,是阻塞中的那个方法抛出这个异常,从而让我们有机会结束这个线程的执行。一个外部的Thread 对象 指向这个线程。 需要结束这个线程时,只需要调用thread对象的interrupt() 方法,就会在responseMessage = this.getSendMessages().take();这条语句中产生一个InterruptedException异常,从而结束该线程的阻塞状态,通过抛出异常,或者break跳出死循环,结束这个线程。

    14.3 线程状态

    Java中线程的状态分为6

     1.初始(NEW):新创建了一个线程对象,但还没有调用start()方法。

    实现Runnable接口和继承Thread可以得到一个线程类,new一个实例出来,线程就进入了初始状态。

    2. 运行(RUNNABLE)Java线程中将就绪(ready)和运行中(running)两种状态统的称为“运行”。

    线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取CPU的使用权,此时处于就绪状态(ready)。就绪状态的线程在获得CPU时间片后变为运行中状态(running)。

     3.阻塞(BLOCKED):表示线程阻塞于锁。

    阻塞状态是线程阻塞在进入synchronized关键字修饰的方法或代码块(获取锁)时的状态

    4. 等待(WAITING):进入该状态的线程需要等待其他线程做出一些特定动作(通知或中断)

    处于这种状态的线程不会被分配CPU执行时间,它们要等待被显式地唤醒,否则会处于无限期等待的状态

    5. 超时等待(TIMED_WAITING):该状态不同于WAITING,它可以在指定的时间后自返回。

    处于这种状态的线程不会被分配CPU执行时间,不过无须无限期等待被其他线程显示地唤醒,在达到一定时间后它们会自动唤醒

    6.终止(TERMINATED):表示该线程已经执行完毕。

    当线程的run()方法完成时,或者主线程的main()方法完成时,我们就认为它终止了。这个线程对象也许是活的,但是,它已经不是一个单独执行的线程。线程一旦终止了,就不能复生。

    在一个终止的线程上调用start()方法,会抛出java.lang.IllegalThreadStateException异常

    第二部分:实验部分

    实验1:测试程序1(10分)

    elipse IDE中调试运行教材585页程序13-1,结合程序运行结果理解程序;

    将所生成的JAR文件移到另外一个不同的目录中,再运行该归档文件,以便确认程序是从JAR文件中,而不是从当前目录中读取的资源。

    掌握创建JAR文件的方法;

    package resource;
     
    import java.awt.*;
    import java.io.*;
    import java.net.*;
    import java.util.*;
    import javax.swing.*;
     
    /**
     * @version 1.41 2015-06-12
     * @author Cay Horstmann
     */
    public class ResourceTest
    {
       public static void main(String[] args)
       {
          EventQueue.invokeLater(() -> {
             JFrame frame = new ResourceTestFrame();
             frame.setTitle("ResourceTest");
             frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
             frame.setVisible(true);
          });
       }
    }
     
    /**
     * A frame that loads image and text resources.
     */
    class ResourceTestFrame extends JFrame
    {
       private static final int DEFAULT_WIDTH = 300;
       private static final int DEFAULT_HEIGHT = 300;
     
       public ResourceTestFrame()
       {
          setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
          URL aboutURL = getClass().getResource("about.gif");//找到指定位置的图像文件,返回一个可以加载资源的URL
          Image img = new ImageIcon(aboutURL).getImage();//将加载的about.gif图像设置为图标
          setIconImage(img);
     
          JTextArea textArea = new JTextArea();
          InputStream stream = getClass().getResourceAsStream("about.txt");//读取about.txt文本文件内容
          try (Scanner in = new Scanner(stream, "UTF-8"))//将读取到的about.txt文本文件里内容显示到文本区
          {
             while (in.hasNext())//读取文本文件
                textArea.append(in.nextLine() + "
    ");
          }
          add(textArea);
       }
    }
    

     运行截图:

     归档截图:

     

     打开后:

    实验1:测试程序2(10分)

    elipse IDE中调试运行ThreadTest,结合程序运行结果理解程序;

    掌握线程概念;

    掌握用Thread的扩展类实现线程的方法;

    利用Runnable接口改造程序,掌握用Runnable接口创建线程的方法。

    class Lefthand extends Thread { 
       public void run()
       {
           for(int i=0;i<=5;i++)
           {  System.out.println("You are Students!");
               try{   sleep(500);   }
               catch(InterruptedException e)
               { System.out.println("Lefthand error.");}    
           } 
      } 
    }
    class Righthand extends Thread {
        public void run()
        {
             for(int i=0;i<=5;i++)
             {   System.out.println("I am a Teacher!");
                 try{  sleep(300);  }
                 catch(InterruptedException e)
                 { System.out.println("Righthand error.");}
             }
        }
    }
    public class ThreadTest 
    {
         static Lefthand left;
         static Righthand right;
         public static void main(String[] args)
         {     left=new Lefthand();
               right=new Righthand();
               left.start();
               right.start();
         }
    }
    packageThread;
    //创建Thread类的子类实现多线程
    class Lefthand extends Thread { 
           public void run()
           {
               for(int i=0;i<=5;i++)
               {  System.out.println("You are Students!");
                   try{   sleep(500);    }//给定休眠的500毫秒,500毫秒打印一次输出语句
                   catch(InterruptedException e)//中断异常情况
                   { System.out.println("Lefthand error.");}    
               } 
          } 
        }
        class Righthand extends Thread {
            public void run()
            {
                 for(int i=0;i<=5;i++)
                 {   System.out.println("I am a Teacher!");
                     try{  sleep(300);  }//给定休眠的300毫秒,300毫秒打印一次输出语句
                     catch(InterruptedException e)
                     { System.out.println("Righthand error.");}
                 }
            }
        }
        public class ThreadTest 
        {
             static Lefthand left;
             static Righthand right;
             public static void main(String[] args)
             {     left=new Lefthand();
                   right=new Righthand();
                   left.start();
                   right.start();//启动线程,调用run()方法,此方法立即返回,新线程并发运行
             }
        }

     实现Runnable之后的代码:

    package Thread
    //实现Runnable接口的类实现多线程
    class Lefthand implements Runnable{
       public void run()
       {
           
           for(int i=0;i<=5;i++)
           {  System.out.println("You are Students!");
               try{ Thread.sleep(500);   }//500毫秒打印一次
               catch(InterruptedException e)//中断异常
               { System.out.println("Lefthand error.");}    
           } 
      } 
    }
    class Righthand implements Runnable {
        public void run()
        {
            for(int i=0;i<=5;i++)
             {   System.out.println("I am a Teacher!");
                 try{  Thread.sleep(300);  }//300毫秒打印一次
                 catch(InterruptedException e)
                 { System.out.println("Righthand error.");}
             }
        }
    }
    public class ThreadTest 
    {
         static Thread left;
         static Thread right;
         public static void main(String[] args)
         {    
               Runnable lefthand = new Lefthand();
               left=new Thread(lefthand);
               left.start();
               Runnable righthand = new Righthand();
               right=new Thread(righthand);
               right.start();
                   
         }
    }
     

    运行截图:

     实验1:测试程序3(10分)

    在Elipse环境下调试教材625页程序14-1、14-2 14-3,结合程序运行结果理解程序;

    在Elipse环境下调试教材631页程序14-4,结合程序运行结果理解程序;

    对比两个程序,理解线程的概念和用途;

    掌握线程创建的两种技术

    程序14-1、14-2 14-3如下:

    package bounce;
     
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
     
    /**
     * 显示了一个滚动的小球
     * @version 1.34 2015-06-21
     * @author Cay Horstmann
     */
    public class Bounce
    {
       public static void main(String[] args)
       {
          EventQueue.invokeLater(() -> {
             JFrame frame = new BounceFrame();
             frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
             frame.setVisible(true);
          });
       }
    }
     
    /**
     *建立有按钮和小球的面板
     */
    class BounceFrame extends JFrame
    {
       private BallComponent comp;
       public static final int STEPS = 1000;
       public static final int DELAY = 3;
     
       /**
        * 创建面板容器显示滚动的小球和两个按钮
        */
       public BounceFrame()
       {
          setTitle("Bounce");
          comp = new BallComponent();
          add(comp, BorderLayout.CENTER);
          JPanel buttonPanel = new JPanel();
          addButton(buttonPanel, "Start", event -> addBall());
          addButton(buttonPanel, "Close", event -> System.exit(0));
          add(buttonPanel, BorderLayout.SOUTH);
          pack();
       }
     
       /**
        * 添加按钮
        * @param 容器c
        * @param 按钮标题
        * @param 按钮动作相应
        */
       public void addButton(Container c, String title, ActionListener listener)
       {
          JButton button = new JButton(title);
          c.add(button);
          button.addActionListener(listener);
       }
     
       /**
        *在面板上添加一个滚动的小球并使它滚动1000次 
        */
       public void addBall()
       {
          try
          {
             Ball ball = new Ball();
             comp.add(ball);
     
             for (int i = 1; i <= STEPS; i++)
             {
                ball.move(comp.getBounds());//小球每一次移动的尺寸
                comp.paint(comp.getGraphics());
                Thread.sleep(DELAY);//3毫秒移动一次 
              }
             } 
    catch (InterruptedException e)
    
     {
     } 
    }
     }
    package bounce;
     
    import java.awt.*;
    import java.util.*;
    import javax.swing.*;
     
    /**
     * The component that draws the balls.
     * @version 1.34 2012-01-26
     * @author Cay Horstmann
     */
    public class BallComponent extends JPanel
    {
       private static final int DEFAULT_WIDTH = 450;
       private static final int DEFAULT_HEIGHT = 350;
     
       private java.util.List<Ball> balls = new ArrayList<>();
     
       /**
        * 在容器上添加一个球
        * @param b the ball to add
        */
       public void add(Ball b)
       {
          balls.add(b);
       }
     
       public void paintComponent(Graphics g)
       {
          super.paintComponent(g);//清除背景 
          Graphics2D g2 = (Graphics2D) g;
          for (Ball b : balls)
          {
             g2.fill(b.getShape());
          }
       }
        
       public Dimension getPreferredSize() { return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT); }
    }
    package bounce;
     
    import java.awt.geom.*;
     
    /**
     * A ball that moves and bounces off the edges of a rectangle
     * @version 1.33 2007-05-17
     * @author Cay Horstmann
     */
    public class Ball
    {
       private static final int XSIZE = 15;
       private static final int YSIZE = 15;
       private double x = 0;
       private double y = 0;
       private double dx = 1;
       private double dy = 1;
     
       /**
        * 将小球移向像一个方向,若打到任何一条边,就颠倒方向
        */
       public void move(Rectangle2D bounds)
       {
          x += dx;
          y += dy;
          if (x < bounds.getMinX())
          {
             x = bounds.getMinX();
             dx = -dx;
          }
          if (x + XSIZE >= bounds.getMaxX())
          {
             x = bounds.getMaxX() - XSIZE;
             dx = -dx;
          }
          if (y < bounds.getMinY())
          {
             y = bounds.getMinY();
             dy = -dy;
          }
          if (y + YSIZE >= bounds.getMaxY())
          {
             y = bounds.getMaxY() - YSIZE;
             dy = -dy;
          }
       }
     
       /**
        *在当前位置得到小球的形状 
        */<br>//定义球外形
    
    public Ellipse2D getShape() { 
       return new Ellipse2D.Double(x, y, XSIZE, YSIZE); 
    }

    运行截图:

     14-4程序:

    package bounceThread;
     
    import java.awt.*;
    import java.awt.event.*;
     
    import javax.swing.*;
     
    /**
     * Shows animated bouncing balls.
     * @version 1.34 2015-06-21
     * @author Cay Horstmann
     */
    public class BounceThread
    {
       public static void main(String[] args)
       {
          EventQueue.invokeLater(() -> {
             JFrame frame = new BounceFrame();
             frame.setTitle("BounceThread");
             frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
             frame.setVisible(true);
          });
       }
    }
     
    /**
     *  框架与球组件和按钮
     */
    class BounceFrame extends JFrame
    {
       private BallComponent comp;
       public static final int STEPS = 1000;
       public static final int DELAY = 5;
     
     
       /**
        * Constructs the frame with the component for showing the bouncing ball and
        * Start and Close buttons
        */
       //用显示弹跳球以及开始和关闭按钮的组件构建框架
       public BounceFrame()
       {
          comp = new BallComponent();
          add(comp, BorderLayout.CENTER);
          JPanel buttonPanel = new JPanel();
          addButton(buttonPanel, "Start", event -> addBall());
          addButton(buttonPanel, "Close", event -> System.exit(0));
          add(buttonPanel, BorderLayout.SOUTH);
          pack();
       }
       // 添加按钮
       /**
        * Adds a button to a container.
        * @param c the container
        * @param title the button title
        * @param listener the action listener for the button
        */
       public void addButton(Container c, String title, ActionListener listener)
       {
          JButton button = new JButton(title);
          c.add(button);
          button.addActionListener(listener);
       }
     
       /**
        * Adds a bouncing ball to the canvas and starts a thread to make it bounce
        */
       //在画布上添加一个弹跳球,并启动一个线程使其弹跳
       public void addBall()
       {
          Ball ball = new Ball();
          comp.add(ball);
          //多线程
          Runnable r = () -> { 
             try
             {  
                for (int i = 1; i <= STEPS; i++)
                {
                   ball.move(comp.getBounds());//将球移动到下一个位置,如果碰到其中一个边缘则反转方向
                   comp.repaint();//重绘此组件
                   Thread.sleep(DELAY);//在指定的毫秒数内让当前正在执行的线程休眠
                }
             }
             catch (InterruptedException e)
             {
             }
          };
          Thread t = new Thread(r);
          t.start();
       }
    }

    运行截图:

     实验总结:(15分)

    本周学习了线程,实现多线程,通过创建Thread类的子类,在程序中实现Runnable接口的类,创建线程的两种方法:
    通过实现Runnable接口,重写其中的run()方法,再调用Thread类的构造方法Thread(Runnable,Threadname)来实现
    通过创建Thread类的子类来实现,即继承Thread类,重写其中的run()方法
    Java 的线程调度采用优先级策略:优先级高的先执行,优先级低的后执行;多线程系统会自动为每个线程分配一个优先级,缺省时,继承其父类的优先级;任务紧急的线程,其优先级较高; 同优先级的线程按“先进先出”的队列原则。线程的六种状态,以及他们之间的状态变换,各个状态的特征,3个测试程让我们对线程有了更直观的体验。
  • 相关阅读:
    118/119. Pascal's Triangle/II
    160. Intersection of Two Linked Lists
    168. Excel Sheet Column Title
    167. Two Sum II
    172. Factorial Trailing Zeroes
    169. Majority Element
    189. Rotate Array
    202. Happy Number
    204. Count Primes
    MVC之Model元数据
  • 原文地址:https://www.cnblogs.com/ylxzjh/p/12049888.html
Copyright © 2011-2022 走看看