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() + "\n");
}
add(textArea);
}
}

运行截图:

归档截图:

打开后:

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

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

l 掌握线程概念;

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

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

class Lefthand extends Thread {
public void run()
{
for(int i=;i<=;i++)
{ System.out.println("You are Students!");
try{ sleep(); }
catch(InterruptedException e)
{ System.out.println("Lefthand error.");}
}
}
}
class Righthand extends Thread {
public void run()
{
for(int i=;i<=;i++)
{ System.out.println("I am a Teacher!");
try{ sleep(); }
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=;i<=;i++)
{ System.out.println("You are Students!");
try{ sleep(); }//给定休眠的500毫秒,500毫秒打印一次输出语句
catch(InterruptedException e)//中断异常情况
{ System.out.println("Lefthand error.");}
}
}
}
class Righthand extends Thread {
public void run()
{
for(int i=;i<=;i++)
{ System.out.println("I am a Teacher!");
try{ sleep(); }//给定休眠的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=;i<=;i++)
{ System.out.println("You are Students!");
try{ Thread.sleep(); }//500毫秒打印一次
catch(InterruptedException e)//中断异常
{ System.out.println("Lefthand error.");}
}
}
}
class Righthand implements Runnable {
public void run()
{
for(int i=;i<=;i++)
{ System.out.println("I am a Teacher!");
try{ Thread.sleep(); }//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分)

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

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

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

掌握线程创建的两种技术

程序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 = ;
public static final int DELAY = ; /**
* 创建面板容器显示滚动的小球和两个按钮
*/
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());
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 = ; 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 = ;
private static final int DEFAULT_HEIGHT = ; 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 = ;
private static final int YSIZE = ;
private double x = ;
private double y = ;
private double dx = ;
private double dy = ; /**
* 将小球移向像一个方向,若打到任何一条边,就颠倒方向
*/
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 = ;
public static final int DELAY = ; /**
* 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());
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 = ; 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个测试程让我们对线程有了更直观的体验。

201871010128-杨丽霞《面向对象程序设计(java)》第十六周学习总结的更多相关文章

  1. 201571030332 扎西平措 《面向对象程序设计Java》第八周学习总结

    <面向对象程序设计Java>第八周学习总结   项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https: ...

  2. 201771010134杨其菊《面向对象程序设计java》第八周学习总结

    第八周学习总结 第一部分:理论知识 一.接口.lambda和内部类:  Comparator与comparable接口: 1.comparable接口的方法是compareTo,只有一个参数:comp ...

  3. 201771010118马昕璐《面向对象程序设计java》第八周学习总结

    第一部分:理论知识学习部分 1.接口 在Java程序设计语言中,接口不是类,而是对类的一组需求描述,由常量和一组抽象方法组成.Java为了克服单继承的缺点,Java使用了接口,一个类可以实现一个或多个 ...

  4. 201771010134杨其菊《面向对象程序设计java》第七周学习总结

    第七周学习总结 第一部分:理论知识 1.继承是面向对象程序设计(Object Oriented Programming-OOP)中软件重用的关键技术.继承机制使用已经定义的类作为基础建立新的类定义,新 ...

  5. 201771010128 王玉兰《面象对象程序设计 (Java) 》第六周学习总结

    ---恢复内容开始--- 第一部分:基础知识总结: 1.继承 A:用已有类来构建新类的一种机制,当定义了一个新类继承一个类时,这个新类就继承了这个类的方法和域以适应新的情况: B:特点:具有层次结构. ...

  6. 201871010126 王亚涛《面向对象程序设计 JAVA》 第十三周学习总结

      内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p/ ...

  7. 马凯军201771010116《面向对象程序设计Java》第八周学习总结

    一,理论知识学习部分 6.1.1 接口概念 两种含义:一,Java接口,Java语言中存在的结构,有特定的语法和结构:二,一个类所具有的方法的特征集合,是一种逻辑上的抽象.前者叫做“Java接口”,后 ...

  8. 周强201771010141《面向对象程序设计Java》第八周学习总结

    一.理论知识学习部分 Java为了克服单继承的缺点,Java使用了接口,一个类可以实现一个或多个接口. 接口体中包含常量定义和方法定义,接口中只进行方法的声明,不提供方法的实现. 类似建立类的继承关系 ...

  9. 201777010217-金云馨《面向对象程序设计Java》第八周学习总结

    项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...

  10. 201871010126 王亚涛 《面向对象程序设计 (Java)》第十七周学习总结

    内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p/12 ...

随机推荐

  1. 有关csp自我反思

    首先说说体会把 这次前几个都是模拟,最后一道题以为自己可能会结果是半吊子根本不会,导致浪费了三个小时写第五题只有十分 如果不畏惧字符串而专心的写第三题的话,应该结果会不一样把.希望下次能好好考 第一题 ...

  2. 【2019.8.12 慈溪模拟赛 T2】汪哥图(wang)(前缀和)

    森林 考虑到题目中给出条件两点间至多只有一条路径. 就可以发现,这是一个森林. 而森林有一个很有用的性质. 考虑对于一棵树,点数-边数=\(1\). 因此对于一个森林,点数-边数=连通块个数. 所以, ...

  3. Spring Security OAuth2学习

    什么是 oAuth oAuth 协议为用户资源的授权提供了一个安全的.开放而又简易的标准.与以往的授权方式不同之处是 oAuth 的授权不会使第三方触及到用户的帐号信息(如用户名与密码),即第三方无需 ...

  4. 使用VisualVM 进行性能分析及调优

    概述 开发大型 Java 应用程序的过程中难免遇到内存泄露.性能瓶颈等问题,比如文件.网络.数据库的连接未释放,未优化的算法等.随着应用程序的持续运行,可能会造成整个系统运行效率下降,严重的则会造成系 ...

  5. 《Linux内核原理与分析》教学进程

    目录 2019-2020-1 <Linux内核原理与分析>教学进程 考核方案 第一周: 第二周: 第三周: 第四周: 第五周 第六周 第七周: 第八周 第九周 第十周 第十一周: 第十二周 ...

  6. 02Shell变量

    Shell变量 什么是 shell 变量 shell变量就是 用一个固定的字符串去表示不固定的内容 变量的类型 自定义变量 定义变量 变量名=变量值 (显式赋值) 变量名必须以字母或下划线开头,区分大 ...

  7. Mybatis中的association用法

    这篇文章我们将来学习一些 association 用法 表结构 DROP TABLE IF EXISTS `student`; CREATE TABLE `student` (  `id` int(1 ...

  8. 解决原生javascript 缺少insertAfter的功能,非Jquery方法

    在现有的方法后插入一个新元素,你可能会想:既然有insertBefore方法,是不是也有一个相应的insertAfter()方法.很可惜,DOM没有提供方法.下面编写insertAfter函数,虽然D ...

  9. 【前端知识体系-JS相关】组件化和React

    1. 说一下使用jQuery和使用框架的区别? 数据和视图的分离,(jQuery数据和视图混在一起,代码耦合)-------开放封闭原则 以数据驱动视图(只关注数据变化,DOM操作被封装) 2.说一下 ...

  10. 使用yarn来替代npm

    Yarn是由Facebook.Google.Exponent 和 Tilde 联合推出了一个新的 JS 包管理工具 ,正如官方文档中写的,Yarn 是为了弥补 npm 的一些缺陷而出现的 安装yarn ...