写在前面

不知不觉《Java核心卷 1》这本书看到最后一章了,时间过得真快啊,估计再有1个月就看完这本书了。

本想着学完这一章之后带大家做个项目,但是发现:卷1居然没有讲全流!那就卷2的流看完了再带大家做项目吧。

预告项目:周报生成器,敬请期待(这一章还有一个月才写完,期待什么啊喂)

第14章 多线程 程序、进程、线程_idea


 14.1 线程的概念

🍡 操作系统多任务:操作系统同时执行多个程序的能力。

🍡 多线程程序:可以同时执行多个任务的程序。

🍡 程序:代码和数据组成的可执行内容。

🍡 进程:正在执行的程序,不同进程间数据隔离,交互困难

🍡 线程:进程中每一个独立执行的任务,一个进程可以有多个线程,不同线程间数据共享,交互容易

单线程造成的问题:无法强制停止重复循环的内容(比如动画弹球,比如大意写出的死循环)。

作者示例:

Ball.java:

❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤

import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;

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);
}
}

❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤

BallComponent.java

❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤

import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;

public class BallComponent extends JPanel {
private ArrayList<Ball> balls = new ArrayList<>();
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());
}
}
}

❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤

Bounce.java

❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class Bounce {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new BounceFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
}

class BounceFrame extends JFrame {
private BallComponent comp;
public static final int WIDTH = 450;
public static final int HEIGHT = 350;
public static final int STEPS = 1000;
public static final int DELAY = 3;
public BounceFrame(){
setSize(WIDTH,HEIGHT);
setTitle("Bounce");

comp = new BallComponent();
add(comp, BorderLayout.CENTER);
JPanel buttonPanel = new JPanel();
addButton(buttonPanel, "Start", new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
addBall();
}
});

addButton(buttonPanel, "Close", new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});

add(buttonPanel,BorderLayout.SOUTH);
}

public void addButton(Container c, String title, ActionListener listener){
JButton button = new JButton(title);
c.add(button);
button.addActionListener(listener);
}

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);
}
}catch (InterruptedException e){

}
}

}

❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤

运行结果:

🍡 点击start,黑色弹球开始运动,点击 close 无法关掉页面

🍡 要等黑球停止后才能关闭页面

🚗🚓🚕🛺🚙🚌🚐🚎🚑🚒🚚🚛🚜🚘🚔🚖🚍🦽🦼🛹🚲🛴🛵🏍

第14章 多线程 程序、进程、线程_java_02

🚗🚓🚕🛺🚙🚌🚐🚎🚑🚒🚚🚛🚜🚘🚔🚖🚍🦽🦼🛹🚲🛴🛵🏍

线程的创建过程:

🍡(1)实现Runnable 接口,重写 run() 方法,class XX implements Runnable{public void run(){//…}}

🍡(2)创建Runnable对象,Runnable r = new XX();

🍡(3)使用 Runnable 创建线程, Thread t = new Thread(r);

🍡(4)执行:t.start();

咱把这个sleep的代码,放入单独线程再试试,如下替换addBall()方法:

❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤

public void addBall(){
Ball ball = new Ball();
comp.add(ball);
Runnable r = new BallRunnable(ball);
Thread t = new Thread(r);
t.start();
}

public class BallRunnable implements Runnable {
Ball ball;

public BallRunnable(Ball b){
this.ball = b;
}

@Override
public void run() {
try{
for(int i = 1; i <= STEPS; i++){
ball.move(comp.getBounds());
comp.paint(comp.getGraphics());
Thread.sleep(DELAY);
}
}catch (InterruptedException e){

}
}
}

❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤

运行结果:

🍡 点击start,黑色弹球开始运动,点击 close 可以关掉页面

小总结:

🍡 需要掌握的知识点:程序、进程、线程

🍡 新学习的内容:线程的启动

🍡 线程的优点,可以同时执行多个不同内容


 14.2 中断线程

🍡 早期线程终止方法:stop(弃用)

🍡 目前可用于终止线程的方法:interrupt

🍡 判断当前线程是否终止:Thread.currentThread().isInterrupted()

🍡 中断结果获取:InterruptedException(建议抛出或者直接调用  Thread.currentThread().isInterrupted()

)

❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤

public class Main {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(new MyRunnble());
t.start();
Thread.sleep(6000);

t.interrupt();
}

static class MyRunnble implements Runnable {
@Override
public void run() {
//注意,这里写成while(true)是停不了的!!!,它没有interrupt打断自动跳出
while (!Thread.currentThread().isInterrupted()) {
System.out.println("alive");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
System.out.println("中断了!");
}

}
}
}

}

❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤

运行结果:

🚗🚓🚕🛺🚙🚌🚐🚎🚑🚒🚚🚛🚜🚘🚔🚖🚍🦽🦼🛹🚲🛴🛵🏍

第14章 多线程 程序、进程、线程_java_03

🚗🚓🚕🛺🚙🚌🚐🚎🚑🚒🚚🚛🚜🚘🚔🚖🚍🦽🦼🛹🚲🛴🛵🏍

相关内容:选择 《Java核心技术 卷1》查找相关笔记

评论🌹点赞👍收藏✨关注👀,是送给作者最好的礼物,愿我们共同学习,一起进步

公众号 钰娘娘知识汇总