项目

内容

这个作业属于哪个课程

<任课教师博客主页链接>

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

这个作业的要求在哪里

<作业链接地址>

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

作业学习目标

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

(2) 掌握线程概念;

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

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

(1) 线程:

多线程是进程执行过程中产生的多条执行线索,线程是比进程执行更小的单位。

线程不能独立存在,必须存在于进程中,同一进程的各线程间共享进程空间的数据。

每个线程有它自身的产生、存在和消亡的过程,是一个动态的概念。

多线程意味着一个程序的多行语句可以看上去几乎在同一时间内同时运行。

线程创建、销毁和切换的负荷远小于进程,又称为轻量级进程。

(2) 线程创建的两种技术;

①创建Thread类的子类

首先须从Thread类派生出一个子类,在该子类中重写run方法。

例:

class hand extends Thread

{

  public void run()

  {……}

}

然后创建该子类的对象

Lefthand left = new Lefthand();

Righthand left = new Righthand();

最后用start()方法启动线程

left.start();

Right.start();

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

首先设计一个实现Runnable接口的类;

然后在类中根据需要重写run方法;

在创建该类对象,以此对象为参数建立Thread类的对象;

(3). 实现多线程的两种方法的差别:

  java不允许多继承,那么我们集成Runnable接口实现多集成就能够很好的避免这个限制.

  集成Runnable接口实现多线程有利于程序操作共享资源(后面会提到)

   我们继承了Thread类实现run方法之后我们可以发现这样一个问题,我们再进行线程实例化之后我们必须分别启动线程任务.

   而我们实现Runnable接口的话,我们可以实例化多个Thread类来运行这个任务.

   当然集成Thread类也并不是不能完成共享资源的分发,而是比较费劲.

 (4)  实例化:我们在初始化Thread类的时候会调用Thread内部的init方法,即便是我们不提供任何参数.init函数的结构:

private void init(ThreadGroup g, Runnable target, String name,long stackSize)

    参数有:ThreadGroup,Target,name.stackSize,

其中ThreadGroup会递归去调用父类的getThreadGroup来进行初始化,

等待初始化完成之后我们会通过ThreadGroup调用checkAccess()方法来检查当前线程是否有权限操作此线程.

 (5)Thread类中的方法:

    Thread.sleep(): sleep方法是使当前线程休眠

    Thread.start: Thread.start方法会启动线程,并且执行run方法中的内容。如果我们调用Thread.run来执行的话,jvm并不会真正的启动一个线程,而是将其当做一个普通的方法执行。而调用start的话,在start内部会调用start0方法来新建一个线程。

第二部分:实验部分

实验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分)

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

掌握线程概念;

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

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

package hi;
//创建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()方法,此方法立即返回,新线程并发运行
}
}

  

package h;
//实现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:测试程序2(10分)

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

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

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

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

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;
}
} /**
*在当前位置得到小球的形状
*/
//定义球外形
public Ellipse2D getShape() { return new Ellipse2D.Double(x, y, XSIZE, YSIZE); } }

  

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分)

本周学习了JAR文件相关的知识,还学习了有关线程的知识,可通过创建Thread类的子类,在程序中定义实现Runnable接口的类的方法实现多线程问题。了解了什么是多线程及其好处。还有很多还有不太理解的地方,之后会慢慢地弄懂,希望在之后的学习中能学到更多。

继承Thread类:创建的线程类继承Thread类,重写其中的run方法,若在主类中调用线程的话,则new出线程类,调用它的start方法即可,这里的start方法完成了两个工作:启动子线程,调用子线程的run方法;

实现Runnable接口:即创建的线程类实现Runnable接口,实现其中的run方法,若在主类中调用线程的话,则new出线程类,这里注意不能直接调用它的start方法,而是通过Thread 线程名 = new Thread(new出来的类),然后调用这个线程的start的方法才能启动线程,反之线程的启动该必须调用start方法!比extends Thread类的方法略微复杂,但这种方式更具优势。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. Redis缓存策略

    常用策略有“求留余数法”和“一致性HASH算法” redis存储的是key,value键值对 一.求留余数法 使用HASH表数据长度对HASHCODE求余数,余数作为索引,使用该余数,直接设置或访问缓 ...

  2. Codeforces Round #551 (Div. 2) E 二分 + 交互

    https://codeforces.com/contest/1153/problem/E 题意 边长为n的正方形里面有一条蛇,每次可以询问一个矩形,然后会告诉你蛇身和矩形相交有几部分,你需要在最多2 ...

  3. 洛谷P3455 [POI2007]ZAP-Queries

    题目大意: 给定\(n,m,k,\) 求 \[\sum\limits_{x=1}^n\sum\limits_{y=1}^m[gcd(x,y)==k]\] 莫比乌斯反演入门题,先进行一步转化,将每个\( ...

  4. 【SpringCloud之pigx框架学习之路 】1.基础环境安装

    [SpringCloud之pigx框架学习之路 ]1.基础环境安装 [SpringCloud之pigx框架学习之路 ]2.部署环境 1.Cmder.exe安装 (1) windows常用命令行工具 下 ...

  5. JWT签名与验签

    签名Token生产 using System; using System.Collections.Generic; using System.IdentityModel.Tokens.Jwt; usi ...

  6. iOS Workflow 分享 - Create QR Code

    上次我分享了一个 Scan QR Code 的 Workflow,这次我分享一个正好相反的.如果我要分享一个 URL(或者是一段非常短的文本)给别人,我就可以用这个 Workflow 来生成 QR C ...

  7. 四、Srping之Bean的初始化和销毁

    Srping之Bean的初始化和销毁方法 通常,bean的初始化和销毁方法我们有三个地方可以入手,分别是: 自定义初始化,销毁方法 实现spring提供的InitializingBean(初始化逻辑) ...

  8. mysql批量更新数据(性能优化) 第一种方式

    首先想到的是,一条一条更新的速度太慢了,然后就想批量更新,一次更新N条数据.实践是检验真理的唯一标准,不一会儿,代码就敲完了,重新试了一下,效果依旧不理想.啊哦,真是要崩溃!后面又想到了利用异步,我一 ...

  9. 解锁云原生 AI 技能|在 Kubernetes 上构建机器学习系统

    本系列将利用阿里云容器服务,帮助您上手 Kubeflow Pipelines. 介绍 机器学习的工程复杂度,除了来自于常见的软件开发问题外,还和机器学习数据驱动的特点相关.而这就带来了其工作流程链路更 ...

  10. Ubuntu 限制 指定端口和IP 访问

    限制端口和IP的时候 要注意别自己登陆不进去了,要不就惨了. 只允许指定的IP访问服务器的指定端口:22 只允许访问的ip: 192.168.1.1 192.168.1.2 192.168.1.3,禁 ...