201871010133-赵永军《面向对象程序设计(java)》第十六周学习总结
项目 | 内容 |
这个作业属于哪个课程 | https://www.cnblogs.com/nwnu-daizh/ |
这个作业的要求在哪里 | https://www.cnblogs.com/nwnu-daizh/p/12031970.html |
作业学习目标 |
(1) 掌握Java应用程序的打包操作; (2) 掌握线程概念; (3) 掌握线程创建的两种技术。 (4) 学习设计应用程序的GUI。 |
第一部分:理论部分
14.1 什么是线程
- Thread 类的静态 sleep 方法将暂停给定的毫秒数。调用 Thread.sleep 不会创建一个新线程, sleep 是 Thread 类的静态方法,用于暂停当前线程的活动。 sleep 方法可以抛出一个 InterruptedException 异常。
- java.lang.Thread 1.0不要调用 Thread 类或 Runnable 对象的 run 方法。直接调用 run 方法,只会执行同一个线程中的任务,并不会启动新线程。应该调用 Thread.start 方法。这个方法将创建一个执行 run 方法的新线程。
- static void sleep(long millis)
休眠给定的毫秒数。
参数:millis 休眠的毫秒数
- static void sleep(long millis)
- java.lang.Thread 1.0
- Thread(Runnable target)
构造一个新线程,用于调用给定target的run()方法。 - void start()
启动这个线程,将引发调用run()方法。这个方法将立即返回,并且新线程将并行运行。 - void run()
调用关联Runnable的run方法。
- Thread(Runnable target)
- java.lang.Runnable 1.0
- void run()
必须覆盖这个方法,并在这个方法中提供所要执行的任务指令。
- void run()
14.2 中断线程
- 当线程的 run 方法执行方法体重最后一条语句后,并经由执行 return 语句返回时,或者出现了在方法中没有捕获的异常时,线程将终止。在Java的早期版本中,还有一个 stop 方法,其他线程可以调用它终止线程。但是,这个方法现在已经被弃用了。
- 有一种可以强制线程终止的方法。然而, interrupt 方法可以用来请求终止线程。
- 当对一个线程调用 interrupt 方法时,线程的中断状态将被置位。这是每一个线程都具有的 boolean 标志。每个线程都应该不时地检查这个标志,以判断线程是否被中断。
- 调用 Thread.currentThread().isInterrputed() 方法获得当前线程的中断状态是否被置位。但是,如果线程被阻塞,就无法检测中断状态。这是产生 InterruptedException 异常的地方。当在一个被阻塞的线程(调用 sleep 或 wait )上调用 interrupt 方法时,阻塞调用将会被 Interrupt Exception 异常中断(存在不能被中断的阻塞 I/O 调用,应该考虑选择可中断的调用)。
- 没有任何语言方面的需求要求一个被中断的线程应该终止。中断一个线程不过是引起它的注意。被中断的线程可以决定如何响应中断。某些线程是如此重要以至于应该处理完异常后,继续执行,而不理会中断。但是,更普通的情况是,线程将简单地将中断作为一个终止的请求。
- 如果在每次工作迭代之后都调用 sleep 方法(或者其他的可中断方法), isInterrpted 检测既没有必要也没有用处。如果在种蒜状态被置位时调用 sleep 方法,它不会休眠。相反,它将清除这一状态(!)并抛出 InterrputedException 。因此,如果你的循环调用 sleep ,不会检测中断状态,相反,需要捕获 InterrputedException 异常。
- 有两个非常类似的方法, interrupted 和 isInterrupted 。 Interrupted 方法是一个静态方法,它检测当前的线程是否被中断。而且,调用 interrupted 方法会清除该线程的中断状态。另一方面, isInterrupted 方法是一个实例方法,可用来检验是否有线程被中断。调用这个方法不会改变中断状态。
- java.lang.Thread 1.0
- void interrupt()
向线程发送中断请求。线程的中断状态将设置为 true 。如果目前该线程被一个 sleep 调用阻塞,那么, InterruptedException 异常被抛出。 - static boolean interrupted()
测试当前线程(即正在执行这一命令的线程)是否被中断。注意,这是一个静态方法。这一调用会产生副作用-它将当前线程的中断状态重置为false。 - boolean isInterrupted()
测试线程是否被终止。不像静态的中断方法,这一调用不改变线程的中断状态。 - static Thread currentThread()
返回代表当前执行线程的 Thread 对象。
- void interrupt()
14.3 线程状态
- 线程可以有如下6种状态:
- New (新创建)
- Runnable (可运行)
- Blocked (被阻塞)
- Waiting (等待)
- Timed waiting (计时等待)
- Terminated (被终止)
14.3.1 新创建线程
- 当用new操作符创建一个新线程,如 new Thread(r) ,该线程还没有开始运行。这意味着它的状态是 new 。当一个线程处于新创建状态时,程序还没有开始运行线程中的代码。在线程运行之前还有一些基本工作要做。
14.3.2 可运行线程
- 一旦调用 start 方法,线程处于 runnable 状态。一个可运行的线程可能正在运行也可能没有运行,这取决于操作系统给线程提供运行的时间。( Java 的规范说明没有将它作为一个单独状态。一个正在运行中的线程仍然处于可运行状态。)
- 一旦一个线程开始运行,它不必始终保持运行。事实上,运行中的线程被中断,目的是为了让其他线程获得运行机会。线程调度的细节依赖于操作系统提供的服务。抢占式调度系统给每一个可运行线程一个时间片来执行任务。当时间片用完,操作系统剥夺该线程的运行权,并给另一个线程运行机会。当选择下一个线程时,操作系统考虑线程的优先级。
- 在任何给定时刻,一个可运行的线程可能正在运行也可能没有运行(这就是为什么将这个状态称为可运行而不是运行)。
14.3.3 被阻塞线程和等待线程
- 当线程处于被阻塞或等待状态时,它暂时不活动。它不运行任何代码且消耗最少资源。直到线程调度器重新激活它。细节取决于它是怎样达到非活动状态的。当一个线程被阻塞或等待时(或终止时),另一个线程被调度为运行状态。当一个线程被重新激活(例如,因为超时期满或成功地获得一个锁),调度器检查它是否具有比当前运行线程更高的优先级。如果是这样,调度器从当前运行线程中挑选一个,剥夺其运行权,选择一个新的线程运行。
- 当一个线程试图获取一个内部的对象锁(而不是 java.util.concurrect 库中的锁),而该锁被其他线程持有,则该线程进入阻塞状态。当所有其他线程释放该锁,并且线程调度器允许本线程持有它的时候,该线程将变成非阻塞状态。
- 当线程等待另一个线程通知调度器一个条件时,它自己进入等待状态。在调用 Object.wait 方法或 Thread.join 方法,或者是等待 java.util.concurrent 库中的 Lock 或 Condition 时,就会出现这种情况。实际上,被阻塞状态与等待状态是由很大不同的。
- 有几个方法有一个超时参数。调用它们导致线程进入计时等待( timed waiting )状态。这一状态将一直保持到超时期满或者接收到适当的通知。带有超时参数的方法有 Thread.sleep 和 Object.wait 、 Thread.join 、 Lock.tryLock 以及 Condition.awit 的计时版。
- 线程状态图
14.3.4 被终止的线程
- 线程因如下两个原因之一而被终止:
- 因为 run 方法正常退出而自然死亡。
- 因为一个没有捕获的异常终止了 run 方法而意外死亡。
特别是,可以调用线程的 stop 方法杀死一个线程。该方法抛出 ThreadDeath 错误对象,由此杀死线程。但是, stop 方法已过时,不要在自己的代码中调用这个方法。
- java.lang.Thread 1.0
- void join()
等待终止指定的线程。 - void join(long millis)
等待指定的线程死亡或者经过指定的毫秒数。 - Thread.State getState() 5.0
得到这一线程的状态:NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING或TERMINATED之一。 - void stop()
停止该线程。这一方法已过时。 - void suspend()
暂停这一线程的执行。这一方法已过时。 - void resume()
恢复线程。这一方法仅仅在调用suspend()之后调用。这一方法已过时。
- void join()
第二部分:实验部分
2、实验内容和步骤
实验1: 导入第13章示例程序,测试程序并进行代码注释。
测试程序1
※在elipse IDE中调试运行教材585页程序13-1,结合程序运行结果理解程序;
※将所生成的JAR文件移到另外一个不同的目录中,再运行该归档文件,以便确认程序是从JAR文件中,而不是从当前目录中读取的资源。
※掌握创建JAR文件的方法;
实验程序如下:
1 import java.awt.*; 2 import java.io.*; 3 import java.net.*; 4 import java.util.*; 5 import javax.swing.*; 6 7 /** 8 * @version 1.41 2015-06-12 9 * @author Cay Horstmann 10 */ 11 public class ResourceTest 12 { 13 public static void main(String[] args) 14 { 15 EventQueue.invokeLater(() -> { 16 JFrame frame = new ResourceTestFrame(); 17 frame.setTitle("ResourceTest"); 18 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 19 frame.setVisible(true); 20 }); 21 } 22 } 23 24 /** 25 * A frame that loads image and text resources. 26 */ 27 class ResourceTestFrame extends JFrame 28 { 29 private static final int DEFAULT_WIDTH = 300; 30 private static final int DEFAULT_HEIGHT = 300;//定义窗口宽和高 31 32 public ResourceTestFrame()//构造器 33 { 34 setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); 35 URL aboutURL = getClass().getResource("about.gif");//URL来指向about.gif资源地址 36 Image img = new ImageIcon(aboutURL).getImage();//利用about.gif图像文件制作图标,在找到ResourceTest类的地方查找about.gif文件 37 setIconImage(img); 38 39 JTextArea textArea = new JTextArea();//创建文本区 40 InputStream stream = getClass().getResourceAsStream("about.txt");//读取about.txt文件 41 try (Scanner in = new Scanner(stream, "UTF-8")) 42 { 43 while (in.hasNext()) 44 textArea.append(in.nextLine() + " "); 45 } 46 add(textArea); 47 } 48 }
程序中用到如下资源:
实验结果如下:
测试程序2:
※在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(); } } |
实验程序如下:
1 class Lefthand extends Thread { 2 public void run() 3 { 4 for(int i=0;i<=5;i++) 5 { System.out.println("You are Students!"); 6 try{ sleep(500); } 7 catch(InterruptedException e) 8 { System.out.println("Lefthand error.");} 9 } 10 } 11 } 12 class Righthand extends Thread { 13 public void run() 14 { 15 for(int i=0;i<=5;i++) 16 { System.out.println("I am a Teacher!"); 17 try{ sleep(300); } 18 catch(InterruptedException e) 19 { System.out.println("Righthand error.");} 20 } 21 } 22 } 23 public class ThreadTest 24 { 25 static Lefthand left; 26 static Righthand right; 27 public static void main(String[] args) 28 { left=new Lefthand(); 29 right=new Righthand(); 30 left.start(); 31 right.start(); 32 } 33 }
使用Runable接口改造后的程序如下:
1 class Lefthand implements Runnable { 2 public void run() 3 { 4 for(int i=0;i<=5;i++) 5 { System.out.println("You are Students!"); 6 try{ Thread.sleep(500);//休眠500毫秒 7 } 8 catch(InterruptedException e) 9 { System.out.println("Lefthand error.");} 10 } 11 } 12 13 } 14 class Righthand implements Runnable { 15 public void run() 16 { 17 for(int i=0;i<=5;i++) 18 { System.out.println("I am a Teacher!"); 19 try{ Thread.sleep(300);//休眠300毫秒 20 } 21 catch(InterruptedException e) 22 { System.out.println("Righthand error.");} 23 } 24 } 25 26 } 27 public class ThreadTest 28 { 29 public static void main(String[] args) 30 { 31 32 Righthand righthand = new Righthand();//新建一个righthand对象 33 Lefthand lefthand = new Lefthand();//新建一个lefthand对象 34 Thread right = new Thread(righthand);//start方法在Thread类中,新建Thread类 35 right.start(); 36 Thread left=new Thread(lefthand); 37 left.start(); 38 } 39 }
实验结果如下:
测试程序3:
※在Elipse环境下调试教材625页程序14-1、14-2 、14-3,结合程序运行结果理解程序;
※在Elipse环境下调试教材631页程序14-4,结合程序运行结果理解程序;
※对比两个程序,理解线程的概念和用途;
※掌握线程创建的两种技术。
实验程序如下:
14-1、14-2 、14-3:
1 import java.awt.*; 2 import java.util.*; 3 import javax.swing.*; 4 5 /** 6 * The component that draws the balls. 7 * @version 1.34 2012-01-26 8 * @author Cay Horstmann 9 */ 10 public class BallComponent extends JPanel 11 { 12 private static final int DEFAULT_WIDTH = 450; 13 private static final int DEFAULT_HEIGHT = 350; 14 15 private java.util.List<Ball> balls = new ArrayList<>(); 16 17 /** 18 * Add a ball to the component. 19 * @param b the ball to add 20 */ 21 public void add(Ball b) 22 { 23 balls.add(b); 24 } 25 26 public void paintComponent(Graphics g) 27 { 28 super.paintComponent(g); // 擦除背景 29 Graphics2D g2 = (Graphics2D) g; 30 for (Ball b : balls) 31 { 32 g2.fill(b.getShape()); 33 } 34 } 35 36 public Dimension getPreferredSize() 37 { 38 return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT); } 39 }
1 import java.awt.*; 2 import java.awt.event.*; 3 import javax.swing.*; 4 5 /** 6 * Shows an animated bouncing ball. 7 * @version 1.34 2015-06-21 8 * @author Cay Horstmann 9 */ 10 public class Bounce 11 { 12 public static void main(String[] args) 13 { 14 EventQueue.invokeLater(() -> { 15 JFrame frame = new BounceFrame(); 16 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 17 frame.setVisible(true); 18 }); 19 } 20 } 21 22 /** 23 * The frame with ball component and buttons. 24 */ 25 class BounceFrame extends JFrame 26 { 27 private BallComponent comp; 28 public static final int STEPS = 1000; 29 public static final int DELAY = 3; 30 31 /** 32 * Constructs the frame with the component for showing the bouncing ball and 33 * Start and Close buttons 34 */ 35 public BounceFrame() 36 { 37 setTitle("Bounce"); 38 comp = new BallComponent(); 39 add(comp, BorderLayout.CENTER);//使用边框布局管理器使其显示在窗口中心位置 40 JPanel buttonPanel = new JPanel(); 41 addButton(buttonPanel, "Start", event -> addBall());//在窗口添加两个按钮 42 addButton(buttonPanel, "Close", event -> System.exit(0)); 43 add(buttonPanel, BorderLayout.SOUTH);//使用边框布局管理器使其显示在窗口下方位置 44 pack(); 45 } 46 47 /** 48 * Adds a button to a container. 49 * @param c the container 50 * @param title the button title 51 * @param listener the action listener for the button 52 */ 53 public void addButton(Container c, String title, ActionListener listener) 54 { 55 JButton button = new JButton(title); 56 c.add(button); 57 button.addActionListener(listener); 58 } 59 60 /** 61 * Adds a bouncing ball to the panel and makes it bounce 1,000 times. 62 */ 63 public void addBall() 64 { 65 try 66 { 67 Ball ball = new Ball(); 68 comp.add(ball); 69 70 for (int i = 1; i <= STEPS; i++) 71 { 72 ball.move(comp.getBounds()); 73 comp.paint(comp.getGraphics()); 74 Thread.sleep(DELAY); 75 } 76 } 77 catch (InterruptedException e) 78 { 79 } 80 } 81 }
1 import java.awt.geom.*; 2 3 /** 4 * A ball that moves and bounces off the edges of a rectangle 5 * @version 1.33 2007-05-17 6 * @author Cay Horstmann 7 */ 8 public class Ball 9 { 10 private static final int XSIZE = 15; 11 private static final int YSIZE = 15; 12 private double x = 0; 13 private double y = 0; 14 private double dx = 1; 15 private double dy = 1; 16 17 /** 18 * 将球移动到下一个位置,如果球碰到其中一条边,则反向移动 19 */ 20 public void move(Rectangle2D bounds) 21 { 22 x += dx; 23 y += dy; 24 if (x < bounds.getMinX()) 25 { 26 x = bounds.getMinX(); 27 dx = -dx; 28 } 29 if (x + XSIZE >= bounds.getMaxX()) 30 { 31 x = bounds.getMaxX() - XSIZE; 32 dx = -dx; 33 } 34 if (y < bounds.getMinY()) 35 { 36 y = bounds.getMinY(); 37 dy = -dy; 38 } 39 if (y + YSIZE >= bounds.getMaxY()) 40 { 41 y = bounds.getMaxY() - YSIZE; 42 dy = -dy; 43 } 44 } 45 46 /** 47 *获取球在当前位置的形状。 48 */ 49 public Ellipse2D getShape() 50 { 51 return new Ellipse2D.Double(x, y, XSIZE, YSIZE); 52 } 53 }
实验结果如下:
14-4:
1 package bounceThread; 2 3 import java.awt.*; 4 import java.awt.event.*; 5 6 import javax.swing.*; 7 8 /** 9 * Shows animated bouncing balls. 10 * @version 1.34 2015-06-21 11 * @author Cay Horstmann 12 */ 13 public class BounceThread 14 { 15 public static void main(String[] args) 16 { 17 EventQueue.invokeLater(() -> { 18 JFrame frame = new BounceFrame(); 19 frame.setTitle("BounceThread"); 20 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 21 frame.setVisible(true); 22 }); 23 } 24 } 25 26 /** 27 * The frame with panel and buttons. 28 */ 29 class BounceFrame extends JFrame 30 { 31 private BallComponent comp; 32 public static final int STEPS = 1000; 33 public static final int DELAY = 5; 34 35 36 /** 37 * Constructs the frame with the component for showing the bouncing ball and 38 * Start and Close buttons 39 */ 40 public BounceFrame() 41 { 42 comp = new BallComponent(); 43 add(comp, BorderLayout.CENTER); 44 JPanel buttonPanel = new JPanel(); 45 addButton(buttonPanel, "Start", event -> addBall()); 46 addButton(buttonPanel, "Close", event -> System.exit(0)); 47 add(buttonPanel, BorderLayout.SOUTH); 48 pack(); 49 } 50 51 /** 52 * Adds a button to a container. 53 * @param c the container 54 * @param title the button title 55 * @param listener the action listener for the button 56 */ 57 public void addButton(Container c, String title, ActionListener listener) 58 { 59 JButton button = new JButton(title); 60 c.add(button); 61 button.addActionListener(listener); 62 } 63 64 /** 65 * Adds a bouncing ball to the canvas and starts a thread to make it bounce 66 */ 67 public void addBall() 68 { 69 Ball ball = new Ball(); 70 comp.add(ball); 71 //引用实现了Runnable的方法 72 Runnable r = () -> { 73 try 74 { 75 for (int i = 1; i <= STEPS; i++) 76 { 77 ball.move(comp.getBounds()); 78 comp.repaint(); 79 Thread.sleep(DELAY); 80 } 81 } 82 catch (InterruptedException e) 83 { 84 } 85 }; 86 Thread t = new Thread(r);//用Runnable创建一个Thread对象 87 t.start();//启动线程 88 } 89 }
实验结果如下:
第一个程序:必须运行结束以后才能关闭;
第二个程序:随时可以关闭;
实验2:
结对编程练习:采用GUI界面设计以下程序,并创建程序归档文件。
设计一个100以内整数小学生四则运算练习程序,由计算机随机产生10道加减乘除练习题,学生输入答案,由程序检查答案是否正确,每道题正确计10分,错误不计分,10道题测试结束后给出测试总分;
将程序中测试练习题及学生答题结果输出到文件,文件名为test.txt。
实验程序如下:
1 import java.awt.*; 2 import javax.swing.*; 3 4 public class DemoTest { 5 public static void main(String[] args) { 6 EventQueue.invokeLater(() -> { 7 JFrame frame = new Demo(); 8 frame.setTitle("计算题"); 9 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 10 frame.setVisible(true); 11 }); 12 } 13 }
1 import java.awt.*; 2 import java.awt.event.ActionEvent; 3 import java.awt.event.ActionListener; 4 import java.io.*; 5 import java.util.*; 6 import javax.swing.*; 7 8 public class Demo extends JFrame { 9 int i = 0; 10 int i1 = 0; 11 int k = 0; 12 int sum = 0; 13 private PrintWriter out = null; 14 private String[] c1 = new String[10]; 15 private String[] c2 = new String[10]; 16 17 public Demo() { 18 JPanel panel = new JPanel(); 19 panel.setLayout(new GridLayout(1, 3)); 20 JTextArea jt1 = new JTextArea(); 21 JTextField jt2 = new JTextField(); 22 JTextArea jt3 = new JTextArea(); 23 panel.add(jt1); 24 panel.add(jt2); 25 panel.add(jt3); 26 add(panel, BorderLayout.NORTH); 27 28 JPanel panel1 = new JPanel(); 29 panel1.setLayout(new GridLayout(1, 2)); 30 Button button1 = new Button("生成题目"); 31 32 Button button2 = new Button("生成文件"); 33 panel1.add(button1); 34 panel1.add(button2); 35 36 add(panel1, BorderLayout.SOUTH); 37 setSize(600, 300); 38 button1.addActionListener(new ActionListener() { 39 40 @Override 41 public void actionPerformed(ActionEvent e) { 42 // TODO 自动生成的方法存根 43 jt2.setText(null); 44 jt3.setText(null); 45 if (i < 10) { 46 int a = (int) (Math.random() * 100); 47 int b = (int) (Math.random() * 100); 48 int m = (int) Math.round(Math.random() * 3); 49 switch (m) { 50 case 0: 51 while (b == 0 || a % b != 0) { 52 b = (int) Math.round(Math.random() * 100); 53 a = (int) Math.round(Math.random() * 100); 54 } 55 jt1.setText(i + 1 + ": " + a + "/" + b + "="); 56 c1[i] = (jt1.getText()); 57 k = a / b; 58 i++; 59 break; 60 case 1: 61 jt1.setText(i + 1 + ": " + a + "*" + b + "="); 62 c1[i] = (jt1.getText()); 63 k = a * b; 64 i++; 65 break; 66 case 2: 67 jt1.setText(i + 1 + ": " + a + "+" + b + "="); 68 c1[i] = (jt1.getText()); 69 k = a + b; 70 i++; 71 break; 72 case 3: 73 while (a < b) { 74 b = (int) Math.round(Math.random() * 100); 75 a = (int) Math.round(Math.random() * 100); 76 } 77 jt1.setText(i + 1 + ": " + a + "-" + b + "="); 78 c1[i] = (jt1.getText()); 79 k = a - b; 80 i++; 81 break; 82 } 83 } 84 } 85 }); 86 jt2.addActionListener(new ActionListener() { 87 88 @Override 89 public void actionPerformed(ActionEvent e) { 90 // TODO 自动生成的方法存根 91 if (i < 11) { 92 int find = Integer.parseInt(jt2.getText()); 93 String d = jt2.getText().toString().trim(); 94 int a = Integer.parseInt(d); 95 if (jt2.getText() != "") { 96 if (find == k) { 97 sum += 10; 98 jt3.setText("答案正确"); 99 } else jt3.setText("答案错误"); 100 } 101 c2[i1] = d; 102 i1++; 103 } 104 } 105 }); 106 button2.addActionListener(new ActionListener() { 107 108 @Override 109 public void actionPerformed(ActionEvent e) { 110 // TODO 自动生成的方法存根 111 try { 112 out = new PrintWriter("text.txt"); 113 } catch (FileNotFoundException e1) { 114 // TODO Auto-generated catch block 115 e1.printStackTrace(); 116 } 117 for (int counter = 0; counter < 10; counter++) { 118 out.println(c1[counter] + c2[counter]); 119 } 120 out.println("成绩" + sum); 121 out.close(); 122 } 123 }); 124 } 125 }
运行界面及导出的jar文件如下:
运行完截图及输出test.txt文件截图:
结对过程描述及结对照片:
第三部分:实验总结
这周主要学习了线程,线程是程序中一个单一的顺序从控制流程。在学习过程中,了解了线程创建的两种技术:用Thread类的子类创建线程以及用Runnable()接口实现线程。但是在实际操作过程中,发现自己还存在着很大的问题。在实验课上老师和学长的帮助西啊,理解了线程中的优先级。课后自己还会再继续学习。