1、实验目的与要求

(1) 掌握线程概念;

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

(3) 理解和掌握线程的优先级属性及调度方法;

(4) 掌握线程同步的概念及实现技术;

一、理论知识

⚫ 线程的概念

(1)多线程是进程执行过程中产生的多条执行线索。

‐线程是比进程执行更小的单位。

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

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

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

(2)Java实现多线程有两种途径: ‐创建Thread类的子类

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

(3)用Thread类的子类创建线程:首先需从Thread类派生出一个子类,在该子类中 重写run()方法,然后用创建该子类的对象,最后用start()方法启动线程。

(4)用Runnable()接口实现线程:首先设计一个实现Runnable接口的类; 然后在类中根据需要重写run方法;  再创建该类对象,以此对象为参数建立Thread 类的对象; 调用Thread类对象的start方法启动线程,将 CPU执行权转交到run方法。

(5)线程两种创建方法比较:

实现Runnable接口的优势: 符合OO设计的思想 •便于用extends继承其它类

采用继承Thread类方法的优点:代码简单

⚫ 中断线程

(1)当线程的run方法执行方法体中最后一条语句后, 或者出现了在run方法中没有捕获的异常时,线 程将终止,让出CPU使用权。

(2)调用interrupt()方法也可终止线程。 void interrupt() – 向一个线程发送一个中断请求,同时把这个线 程的“interrupted”状态置为true。

(3)Java提供了几个用于测试线程是否被中断的方法。 ⚫ static boolean interrupted() – 检测当前线程是否已被中断 , 并重置状态 “interrupted”值为false。 ⚫ boolean isInterrupted() – 检测当前线程是否已被中断 , 不改变状态 “interrupted”值 。

⚫ 线程状态

(1)利用各线程的状态变换,可以控制各个线程轮流 使用CPU,体现多线程的并行性特征。

(2)线程有如下7种状态: ➢ New (新建) ➢ Runnable (可运行) ➢ Running(运行) ➢ Blocked (被阻塞) ➢ Waiting (等待) ➢ Timed waiting (计时等待) ➢ Terminated (被终止)

(3)其他判断和影响线程状态的方法:

➢join():等待指定线程的终止。

➢join(long millis):经过指定时间等待终止指定 的线程。

➢isAlive():测试当前线程是否在活动。

➢yield():让当前线程由“运行状态”进入到“就 绪状态” ,从而让其它具有相同优先级的等待线程 获取执行权。

⚫ 多线程调度

(1)Java提供一个线程调度器来监控程序启动后进入 可运行状态的所有线程。线程调度器按照线程的 优先级决定应调度哪些线程来执行。

(2)Java 的线程调度采用优先级策略:

➢ 优先级高的先执行,优先级低的后执行;

➢ 多线程系统会自动为每个线程分配一个优先级,缺省 时,继承其父类的优先级;

➢ 任务紧急的线程,其优先级较高;

➢ 同优先级的线程按“先进先出”的队列原则;

(3)调用setPriority(int a)重置当前线程的优先级, a 取值可以是前述的三个静态量。

调用getPriority()获得当前线程优先级。

(4)下面几种情况下,当前运行线程会放弃CPU: – 线程调用了yield() 或sleep() 方法;

– 抢先式系统下,有高优先级的线程参与调度;

– 由于当前线程进行I/O访问、外存读写、等待用 户输入等操作导致线程阻塞;或者是为等候一 个条件变量,以及线程调用wait() 方法。

⚫ 线程同步

(1)多线程并发运行不确定性问题解决方案:引入线 程同步机制,使得另一线程要使用该方法,就只 能等待

(2)在Java中解决多线程同步问题的方法有两种:

解决方案一:锁对象与条件对象

用ReentrantLock保护代码块的基本结构如下: myLock.lock();

try { critical section }

finally{ myLock.unlock(); }

(3)解决方案二: synchronized关键字

synchronized关键字作用: ➢ 某个类内方法用synchronized 修饰后,该方 法被称为同步方法;

➢ 只要某个线程正在访问同步方法,其他线程欲要访问同步方法就被阻塞,直至线程从同步方法返回前唤醒被阻塞线程,其他线程方可能进入同步方法。

(4)在同步方法中使用wait()、notify 和notifyAll()方法

一个线程在使用的同步方法中时,可能根据问题 的需要,必须使用wait()方法使本线程等待,暂 时让出CPU的使用权,并允许其它线程使用这个 同步方法。

线程如果用完同步方法,应当执行notifyAll()方 法通知所有由于使用这个同步方法而处于等待的 线程结束等待。

二、实验内容和步骤

实验1:测试程序并进行代码注释。

测试程序1:

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{ Thread.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{Thread.sleep(); }
catch(InterruptedException e)
{ System.out.println("Righthand error.");}
}
}
}
public class ThreadTest
{
static Lefthand left;
static Righthand right;
public static void main(String[] args)
{ Runnable left=new Lefthand();
Runnable right=new Righthand();
Thread t=new Thread(left);
Thread s=new Thread(right);
left=new Lefthand();
right=new Righthand();
t.start();
s.start();
}
}

Thread

测试程序2:

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

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

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

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

(1)

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; /**
* Moves the ball to the next position, reversing direction if it hits one of the edges
*/
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;
}//四次定义移动逻辑,
} /**
* Gets the shape of the ball at its current position.
*/
public Ellipse2D getShape()
{
return new Ellipse2D.Double(x, y, XSIZE, YSIZE);
}
}

Ball

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<>(); /**
* Add a ball to the component.
* @param b the ball to add
*/
public void add(Ball b)
{
balls.add(b);
} public void paintComponent(Graphics g)
{
super.paintComponent(g); // erase background
Graphics2D g2 = (Graphics2D) g;
for (Ball b : balls)
{
g2.fill(b.getShape());
}
} public Dimension getPreferredSize() { return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT); }
}

BallComponent

package bounce;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*; /**
* Shows an animated bouncing ball.
* @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);//结果可见
});
}
} /**
* The frame with ball component and buttons.
*/
class BounceFrame extends JFrame
{
private BallComponent comp;
public static final int STEPS = 1000;
public static final int DELAY = 3; /**
* Constructs the frame with the component for showing the bouncing ball and
* Start and Close buttons
*/
public BounceFrame()
{
setTitle("Bounce");
comp = new BallComponent();
add(comp, BorderLayout.CENTER);//放到框架居中位置
JPanel buttonPanel = new JPanel();
addButton(buttonPanel, "Start", event -> addBall());//按钮对象添加到buttonPanel中
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);//生成title按钮
c.add(button);
button.addActionListener(listener);
} /**
* Adds a bouncing ball to the panel and makes it bounce 1,000 times.
*/
public void addBall()
{
try
{
Ball ball = new Ball();
comp.add(ball); for (int i = 1; i <= STEPS; i++)
{
ball.move(comp.getBounds());//调用move方法来显示
comp.paint(comp.getGraphics());
Thread.sleep(DELAY);//休眠
}
}
//抛出异常
catch (InterruptedException e)
{
}
}
}

Bounce

(2)   前两个程序如(1)所示,

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);
});
}
} /**
* The frame with panel and buttons.
*/
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 = () -> { //实现一个BallRunnable类,将动画代码放到run方法中
try
{
for (int i = 1; i <= STEPS; i++)
{
ball.move(comp.getBounds());
comp.repaint();
Thread.sleep(DELAY);//捕获sleep方法抛出的异常InterruptedException
}
}
catch (InterruptedException e)
{
}
};
Thread t = new Thread(r);
t.start();
}
}

BounceThread

测试程序3:分析以下程序运行结果并理解程序。

class Race extends Thread {
public static void main(String args[]) {
Race[] runner=new Race[4];
for(int i=0;i<4;i++)
runner[i]=new Race( );
for(int i=0;i<4;i++)
runner[i].start( );
runner[1].setPriority(MIN_PRIORITY);//设置线程的最小优先级
runner[3].setPriority(MAX_PRIORITY);}//设置线程的最大优先级
public void run( ) {
for(int i=0; i<1000000; i++);//延时作用,执行空语句
System.out.println(getName()+"线程的优先级是"+getPriority()+"已计算完毕!");
}
}

测试程序4

l 教材642页程序模拟一个有若干账户的银行,随机地生成在这些账户之间转移钱款的交易。每一个账户有一个线程。在每一笔交易中,会从线程所服务的账户中随机转移一定数目的钱款到另一个随机账户。

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

bank

package unsynch;

/**
* This program shows data corruption when multiple threads access a data structure.
* @version 1.31 2015-06-21
* @author Cay Horstmann
*/
public class UnsynchBankTest
{
public static final int NACCOUNTS = 100;
public static final double INITIAL_BALANCE = 1000;
public static final double MAX_AMOUNT = 1000;
public static final int DELAY = 10; public static void main(String[] args)
{
Bank bank = new Bank(NACCOUNTS, INITIAL_BALANCE);
for (int i = 0; i < NACCOUNTS; i++)
{
int fromAccount = i;
Runnable r = () -> {
try
{
while (true)
{
int toAccount = (int) (bank.size() * Math.random());
double amount = MAX_AMOUNT * Math.random();
bank.transfer(fromAccount, toAccount, amount);
Thread.sleep((int) (DELAY * Math.random()));
}
}
catch (InterruptedException e)
{
}
};
Thread t = new Thread(r);
t.start();
}
}
}

UnsynchBankTest

综合编程练习

编程练习1

  1. 设计一个用户信息采集程序,要求如下:

(1) 用户信息输入界面如下图所示:

(1) 用户点击提交按钮时,用户输入信息显示控制台界面;

(2) 用户点击重置按钮后,清空用户已输入信息;

(3) 点击窗口关闭,程序退出。

import java.awt.EventQueue;

import javax.swing.JFrame;

public class Main {
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
DemoJFrame page = new DemoJFrame();
});
}
}

Main

import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.Window; public class WinCenter {
public static void center(Window win){
Toolkit tkit = Toolkit.getDefaultToolkit();
Dimension sSize = tkit.getScreenSize();
Dimension wSize = win.getSize();
if(wSize.height > sSize.height){
wSize.height = sSize.height;
}
if(wSize.width > sSize.width){
wSize.width = sSize.width;
}
win.setLocation((sSize.width - wSize.width)/ 2, (sSize.height - wSize.height)/ 2);
}
}

WinCenter

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
public class DemoJFrame extends JFrame {
public DemoJFrame() {
JPanel panel1 = new JPanel();
panel1.setPreferredSize(new Dimension(700, 45));
panel1.setLayout(new GridLayout(1, 4));
JLabel label1 = new JLabel("Name:");
JTextField j1 = new JTextField("");
JLabel label2 = new JLabel("Qualification:");
JComboBox<Object> j2 = new JComboBox<>();
j2.addItem("chuzhong");
j2.addItem("gaozhong");
j2.addItem("undergraduate");
panel1.add(label1);
panel1.add(j1);
panel1.add(label2);
panel1.add(j2); JPanel panel2 = new JPanel();
panel2.setPreferredSize(new Dimension(700, 65));
panel2.setLayout(new GridLayout(1, 4));
JLabel label3 = new JLabel("Address:");
JTextArea j3 = new JTextArea();
JLabel label4 = new JLabel("Hobby:");
JPanel p = new JPanel();
p.setLayout(new GridLayout(3, 1));
p.setBorder(BorderFactory.createLineBorder(null));
JCheckBox c1 = new JCheckBox("Reading");
JCheckBox c2 = new JCheckBox("Singing");
JCheckBox c3 = new JCheckBox("Dancing");
p.add(c1);
p.add(c2);
p.add(c3);
panel2.add(label3);
panel2.add(j3);
panel2.add(label4);
panel2.add(p); JPanel panel3 = new JPanel();
panel3.setPreferredSize(new Dimension(700, 150));
FlowLayout flowLayout1 = new FlowLayout(FlowLayout.LEFT, 70, 40);
panel3.setLayout(flowLayout1);
JLabel label5 = new JLabel("Sex:");
JPanel p1 = new JPanel();
p1.setLayout(new GridLayout(2,1));
p1.setBorder(BorderFactory.createLineBorder(null));
ButtonGroup bu = new ButtonGroup();
JRadioButton jr1 = new JRadioButton("Male");
JRadioButton jr2 = new JRadioButton("Female");
bu.add(jr1);
bu.add(jr2);
p1.add(jr1);
p1.add(jr2);
panel3.add(label5);
panel3.add(p1);
add(panel1);
add(panel2);
add(panel3); JPanel panel4 = new JPanel();
panel4.setPreferredSize(new Dimension(700, 150));
JButton b1 = new JButton("Validate");
panel4.add(b1);
JButton b2 = new JButton("Reset");
panel4.add(b2);
add(panel4); FlowLayout flowLayout = new FlowLayout();
this.setLayout(flowLayout);
this.setTitle("Students Detail");
this.setBounds(300, 300, 800, 400);
this.setVisible(true);
this.setDefaultCloseOperation(DISPOSE_ON_CLOSE); b1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) {
// TODO 自动生成的方法存根
String xueli = j2.getSelectedItem().toString();
System.out.println("Name:" + j1.getText());
System.out.println("Qualification:" + xueli);
String hobbystring = "Hobby:";
if (c1.isSelected()) {
hobbystring += "Reading";
}
if (c2.isSelected()) {
hobbystring += "Singing";
}
if (c3.isSelected()) {
hobbystring += "Dancing";
}
System.out.println("Address:" + j3.getText());
if (jr1.isSelected()) {
System.out.println("Sex:Male");
}
if (jr2.isSelected()) {
System.out.println("Sex:Female");
}
System.out.println(hobbystring);
}
});
b2.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) {
// TODO 自动生成的方法存根
j1.setText(null);
j3.setText(null);
j2.setSelectedIndex(0);
c1.setSelected(false);
c2.setSelected(false);
c3.setSelected(false);
bu.clearSelection();
}
});
} public static void main(String args[]) {
new DemoJFrame();
} }

DemoJFrame

结果如下:

重置:

2.创建两个线程,每个线程按顺序输出5次“你好”,每个“你好”要标明来自哪个线程及其顺序号。

class Lefthand implements Runnable {
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(i + 1 + ":first.你好!");
try {
Thread.sleep(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 + 1 + ":second.你好!");
try {
Thread.sleep(300);
} catch (InterruptedException e) {
System.out.println("Righthand error.");
}
}
}
} public class ThreadTest {
public static void main(String[] args) {
Runnable left = new Lefthand();
Thread l = new Thread(left);
Runnable right = new Righthand();
Thread r = new Thread(right);
l.start();
r.start();
}
}

ThreadTest

3. 完善实验十五 GUI综合编程练习程序。

1、

package 身份证;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Scanner;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*; public class Main extends JFrame {
private static ArrayList<Student> studentlist;
private static ArrayList<Student> list;
private JPanel panel;
private JPanel buttonPanel;
private static final int DEFAULT_WITH = 900;
private static final int DEFAULT_HEIGHT = 500; public Main() {
studentlist = new ArrayList<>();
Scanner scanner = new Scanner(System.in);
File file = new File("D:\\java\\身份证号.txt");
try {
FileInputStream fis = new FileInputStream(file);
BufferedReader in = new BufferedReader(new InputStreamReader(fis));
String temp = null;
while ((temp = in.readLine()) != null) { Scanner linescanner = new Scanner(temp); linescanner.useDelimiter(" ");
String name = linescanner.next();
String number = linescanner.next();
String sex = linescanner.next();
String age = linescanner.next();
String province = linescanner.nextLine();
Student student = new Student();
student.setName(name);
student.setnumber(number);
student.setsex(sex);
int a = Integer.parseInt(age);
student.setage(a);
student.setprovince(province);
studentlist.add(student); }
} catch (FileNotFoundException e) {
System.out.println("学生信息文件找不到");
e.printStackTrace();
} catch (IOException e) {
System.out.println("学生信息文件读取错误");
e.printStackTrace();
}
panel = new JPanel();
panel.setLayout(new BorderLayout());
JTextArea jt = new JTextArea();
panel.add(jt);
add(panel, BorderLayout.NORTH);
buttonPanel = new JPanel();
buttonPanel.setLayout(new GridLayout(1, 8));
JButton jButton = new JButton("字典排序");
JButton jButton1 = new JButton("年龄最大和年龄最小");
JLabel lab = new JLabel("查找你的同乡");
JTextField jt1 = new JTextField();
JLabel lab1 = new JLabel("查找与你年龄相近的人:");
JTextField jt2 = new JTextField();
JLabel lab2 = new JLabel("输入你的身份证号码:");
JTextField jt3 = new JTextField();
JButton jButton2 = new JButton("退出");
jButton.setBounds(900, 200,100, 90);
jButton1.setBounds(50, 120, 90, 60);
jt1.setBounds(900, 120, 100, 80);
jt2.setBounds(800, 200, 100, 80);
jt3.setBounds(450, 120, 80, 90);
jButton2.setBounds(800,200, 60, 50);
jButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Collections.sort(studentlist);
jt.setText(studentlist.toString());
}
});
jButton1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int max = 0, min = 100;
int j, k1 = 0, k2 = 0;
for (int i = 1; i < studentlist.size(); i++) {
j = studentlist.get(i).getage();
if (j > max) {
max = j;
k1 = i;
}
if (j < min) {
min = j;
k2 = i;
} }
jt.setText("年龄最大:" + studentlist.get(k1) + "年龄最小:" + studentlist.get(k2));
}
});
jButton2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dispose();
System.exit(0);
}
});
jt1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String find = jt1.getText();
String text="";
String place = find.substring(0, 3);
for (int i = 0; i < studentlist.size(); i++) {
if (studentlist.get(i).getprovince().substring(1, 4).equals(place)) {
text+="\n"+studentlist.get(i);
jt.setText("老乡:" + text);
}
}
}
});
jt2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String yourage = jt2.getText();
int a = Integer.parseInt(yourage);
int near = agenear(a);
int value = a - studentlist.get(near).getage();
jt.setText("年龄相近:" + studentlist.get(near));
}
});
jt3.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
list = new ArrayList<>();
Collections.sort(studentlist);
String key = jt3.getText();
for (int i = 1; i < studentlist.size(); i++) {
if (studentlist.get(i).getnumber().contains(key)) {
list.add(studentlist.get(i));
jt.setText("你或许是:\n" + list); }
}
}
});
buttonPanel.add(jButton);
buttonPanel.add(jButton1);
buttonPanel.add(lab);
buttonPanel.add(jt1);
buttonPanel.add(lab1);
buttonPanel.add(jt2);
buttonPanel.add(lab2);
buttonPanel.add(jt3);
buttonPanel.add(jButton2);
add(buttonPanel, BorderLayout.SOUTH);
setSize(DEFAULT_WITH, DEFAULT_HEIGHT);
} public static int agenear(int age) {
int min = 53, value = 0, k = 0;
for (int i = 0; i < studentlist.size(); i++) {
value = studentlist.get(i).getage() - age;
if (value < 0)
value = -value;
if (value < min) {
min = value;
k = i;
}
}
return k;
} }

Main

package 身份证;

public class Student implements Comparable<Student> {

    private String name;
private String number ;
private String sex ;
private int age;
private String province; public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getnumber() {
return number;
}
public void setnumber(String number) {
this.number = number;
}
public String getsex() {
return sex ;
}
public void setsex(String sex ) {
this.sex =sex ;
}
public int getage() { return age;
}
public void setage(int age) {
// int a = Integer.parseInt(age);
this.age= age;
} public String getprovince() {
return province;
}
public void setprovince(String province) {
this.province=province ;
} public int compareTo(Student o) {
return this.name.compareTo(o.getName());
} public String toString() {
return name+"\t"+sex+"\t"+age+"\t"+number+"\t"+province+"\n";
}
}

Student

package 身份证;

import java.awt.*;
import javax.swing.*; public class ButtonText {
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
JFrame frame = new Main();
frame.setTitle("身份证");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
});
}
}

ButtonText

2、

package 答题;

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.util.Random;
import javax.swing.*; public class Exam extends JFrame {
JPanel p=new JPanel();
JLabel timeLabel=new JLabel(); JLabel[] label1=new JLabel[10];
JLabel[] label2=new JLabel[10];
JLabel[] label3=new JLabel[10];
JLabel[] label4=new JLabel[10];
JLabel[] label5=new JLabel[10];
JTextField[] field=new JTextField[10];
JLabel[] label6=new JLabel[10];
String[] btn_name= {"开始","重置","提交","重考"};
JButton[] btn=new JButton[4];
Panel2 panel2=null;
int ExamCount=0;
JLabel examLabel=new JLabel();
double[] result=new double[10];
public static void main(String[] args) {
new Exam("测试").setVisible(true);
} public Exam(String title) {
setTitle(title);
setLocationRelativeTo(null);
setDefaultCloseOperation(3);
setSize(400,500);
setResizable(false);
setForeground(Color.blue);
add(new Panel1(),BorderLayout.NORTH);
panel2=new Panel2();
add(new JScrollPane(panel2));
add(new Panel3(),BorderLayout.WEST);
} int rightResultCount=0;
public void startExam() {
int num1=0;
int num2=0;
String[] quots= {"+","-","*","/"};
String quot=null;
Random ran=null;
ran=new Random(System.currentTimeMillis());
Box box=Box.createVerticalBox(); for(int i=0;i<10;i++) {
num1=ran.nextInt(100)+1;
num2=ran.nextInt(100)+1;
int n=ran.nextInt(4);
quot=new String(quots[n]);
switch(quot) {
case "+":
result[i]=num1+num2;
break;
case "-":
result[i]=num1-num2;
break;
case "*":
result[i]=num1*num2;
break;
case "/":
result[i]=num1/(num2*1.0);
result[i]=Math.round(result[i]*100)/100.0;
break;
} label1[i]=new JLabel("第"+(i+1)+"题:");
label2[i]=new JLabel(num1+""); label3[i]=new JLabel(quot);
label4[i]=new JLabel(num2+"");
label5[i]=new JLabel("=");
field[i]=new JTextField();
field[i].setPreferredSize(new Dimension(60,20));
field[i].addKeyListener(new KeyAdapter() {
public void keyTyped(KeyEvent ee) {
if((ee.getKeyChar()>'9' || ee.getKeyChar()<'0') && ee.getKeyChar()!=45 && ee.getKeyChar()!='.') {
ee.consume();
}
}
});
label6[i]=new JLabel("");
Box hbox=Box.createHorizontalBox();
hbox.add(label1[i]);
hbox.add(Box.createHorizontalStrut(20));
hbox.add(label2[i]);
hbox.add(Box.createHorizontalStrut(5));
hbox.add(label3[i]);
hbox.add(Box.createHorizontalStrut(5));
hbox.add(label4[i]);
hbox.add(Box.createHorizontalStrut(5));
hbox.add(label5[i]);
hbox.add(Box.createHorizontalStrut(5));
hbox.add(field[i]);
hbox.add(Box.createHorizontalStrut(20));
hbox.add(label6[i]);
box.add(hbox);
box.add(Box.createVerticalStrut(20));
}
panel2.add(box);
panel2.validate();
}
int submitCount=0;
class Listener implements ActionListener{
public void actionPerformed(ActionEvent e) {
JButton button=(JButton)e.getSource();
if(button==btn[0]) {
startExam();
ExamCount++;
btn[0].setEnabled(false); for(int i=1;i<4;i++) {
btn[i].setEnabled(true);
}
}
if(button==btn[1]) {
for(int i=0;i<10;i++) {
field[i].setText("");
}
}
if(button==btn[2] ) {
rightResultCount=0;
btn[2].setEnabled(false);
double yourResult=0;
for(int i=0;i<10;i++) {
try {
yourResult=Double.parseDouble(field[i].getText().trim());
}catch(Exception ee) {} if(yourResult==result[i]) {
rightResultCount++;
label6[i].setText("V");
label6[i].setForeground(Color.BLUE); }else {
label6[i].setText("X");
label6[i].setForeground(Color.RED); }
}
examLabel.setText("你答对了 "+rightResultCount+
" 道题,答错了"+(10-rightResultCount)+" 道题!"+
"考试得分是: "+rightResultCount*10+" 分!");
}
if(button==btn[3]) {
btn[2].setEnabled(true);
panel2.removeAll();
startExam();
ExamCount++;
btn[3].setEnabled(false);
for(int i=0;i<10;i++) {
field[i].setText("");
label6[i].setText("");
}
panel2.repaint();
}
if(btn[2].isEnabled()==false && btn[3].isEnabled()==false) {
btn[1].setEnabled(false);
}
}
} class Panel1 extends JPanel{
public Panel1() {
setPreferredSize(new Dimension(350,120));
setLayout(new GridLayout(3,1,10,10));
JTextArea area=new JTextArea("点击“开始”开始答题,答案中有小数的,保留2位!");
area.setLineWrap(true);
area.setEditable(false);
add(area);
add(examLabel);
p.add(timeLabel);
add(p);
}
} class Panel2 extends JPanel{
public Panel2() {
setPreferredSize(new Dimension(400,600));
}
} class Panel3 extends JPanel{
public Panel3() {
setPreferredSize(new Dimension(50,100));
setBackground(Color.LIGHT_GRAY);
for(int i=0;i<4;i++) {
btn[i]=new JButton(btn_name[i]);
btn[i].addActionListener(new Listener());
add(btn[i]);
if(i>0) {
btn[i].setEnabled(false);
}
}
}
}
}

三、总结

本周我们学习了有关线程的知识,了解了什么是多线程及其好处,编程实验在学长的演示和上课老师的讲解下,也做出来了,对于理论知识,还得多看书来熟记。

201771010135 杨蓉庆《面对对象程序设计(java)》第十六周学习总结的更多相关文章

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

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

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

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

  3. 201771010135杨蓉庆《面向对象程序设计(java)》第四周学习总结

    学习目标 1.掌握类与对象的基础概念,理解类与对象的关系: 2.掌握对象与对象变量的关系: 3.掌握预定义类的基本使用方法,熟悉Math类.String类.math类.Scanner类.LocalDa ...

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

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

  5. 201771010135杨蓉庆 《面向对象程序设计(java)》第三周学习总结

    一:第1-3章学习内容: 第一章:复习基本数据类型 整型 byte(1个字节 表示范围:-2^7 ~ (2^7)-1) short(2个字节 表示范围:-2^15~(2^15)-1) int(4个字节 ...

  6. 201771010135杨蓉庆《面向对象程序设计(java)》第六周学习总结

    实验六 继承定义与使用 1.实验目的与要求 (1) 理解继承的定义: (2) 掌握子类的定义要求 (3) 掌握多态性的概念及用法: (4) 掌握抽象类的定义及用途: (5) 掌握类中4个成员访问权限修 ...

  7. 201771010135杨蓉庆《面向对象程序设计(java)》第二周学习总结

    第一部分:理论知识学习部分 3.1 标识符:由字母.下划线.美元符号和数字组成, 且第一个符号不能为数字,可用作:类名.变量名.方法名.数组名.文件名等.有Hello.$1234.程序名.www_12 ...

  8. 201771010134杨其菊《面向对象程序设计(java)》第十六周学习总结

    第十六周学习总结 第一部分:理论知识 1. 程序是一段静态的代码,它是应用程序执行的蓝本.进程是程序的一次动态执行,它对应了从代码加载.执行至执行完毕的一个完整过程.操作系统为每个进程分配一段独立的内 ...

  9. 201521123061 《Java程序设计》第十二周学习总结

    201521123061 <Java程序设计>第十二周学习总结 1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多流与文件相关内容. 2. 书面作业 将Student对 ...

  10. 201521123072《java程序设计》第十二周学习总结

    201521123072<java程序设计>第十二周学习总结 1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多流与文件相关内容. 2. 书面作业 将Student对象 ...

随机推荐

  1. Ajax返回值一直获取不到啊

      原理: 同步异步的问题 Return 位置的问题     首先同步异步改为async : false,   Return 的值写在ajax外部  function submit_answer(){ ...

  2. Oracle tnsnames.ora

    安装过ORACLE的都知道,oracle安装时需要进行配置,这个配置可以在客户端的企业管理器一步一步进行,或者直接拷贝一个tnsnames.ora文件到安装目录下(c:\app\Administrat ...

  3. Big research problems (1)

    1. how to measure the uncertainty of prediction model or data analysis? 2.

  4. <<甄嬛传>>后感

    2020年疫情和休假的时间里,刷了几部喜欢的电视剧,从<好先生>孙红雷和车晓的现代剧,到刷了至少6遍的<新三国>后,一直想了解司马懿和曹丕,接着就到了<大军师司马懿之军师 ...

  5. linux做免密登录,成功分发公钥后登录主机依旧需要输入密码的问题解决

    问题描述 在主机A上用ssh-keygen生成密钥对后,用ssh-copy-id命令将公钥成功copy到主机B上后,测试从A免密登录B,但是依旧需要输入主机B的密码后才能登录. 出现此错误的原因 如果 ...

  6. JavaScript对象之get/set方法

    我们可以重写js对象属性的get和set方法. 从上图我们可以看出set和get的语法. 上图则是使用set和get方法对对象的属性进行了输入校验. 从上图可得若对象的原型链上具有不可配置的同名属性( ...

  7. vue基础实例

    <html> <head> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"> ...

  8. 结构struct 联合Union和枚举Enum的细节讨论

    联合(Union)是一种构造数据类型,它提供了一种使不同类型数据类型成员之间共享存储空间的方法,同时可以实现不同类型数据成员之间的自动类型转换.联合体对象在同一时间只能存储一个成员的值.联合的内存大小 ...

  9. jvm(2):垃圾收集和内存分配

    typora-root-url: ./ 垃圾收集 垃圾收集器关注的是线程共享的这部分内存. jvisualvm用来监控JVM的运行情况,可以用它来查看和浏览Heap Dump.Thread Dump. ...

  10. 美化git commit历史

    为什么要美化commit历史? 答:假如一个分支的多次意义相近的 commit,会把整个提交历史搞得很混乱, 此时可以将几个commit 合并为一个 commit,以美化整个 commit 历史. 怎 ...