并发-1-从直观的swing弹球感受并发

3 篇文章 0 订阅

大家好,从今天开始,有计划的恶补一下并发知识。

目录见:目录

示例代码来源

《Java核心技术 卷1 第10版》 Core Java Volume I-Fundamentals(10th Edition)
[美] Cay S.Horstmann 著
周立新 陈波 叶乃文 邝劲筠 杜永萍 译

一、效果图

在这里插入图片描述
上图的却显示无法通过多次点击Start出现多个弹球,Close也没法关闭。

在这里插入图片描述
上图用到了线程,可发射多个弹球并且可Close。

二、示例代码

git仓库 git@github.com:cmhhcm/guiAndConcurrent.git

1、无线程代码

package com.cmh.concurrent;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.EventQueue;
import java.awt.event.ActionListener;

/**
 * 核心类-绘制图形并使球弹跳
 * 
 * Author: cmh
 * Date:2021/4/18 1:39 上午
 */
public class Bounce {
    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            JFrame frame = new BounceFrame();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
        });
    }

    static class BounceFrame extends JFrame {
        private BallComponent comp;
        public static final int STEPS = 5000000;
        public static final int DELAY = 8;

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

        /**
         * Adds a button to a container
         */
        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 panel and makes it bounce N times
         */
        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) {
                e.printStackTrace();
            }
        }
    }
}

Ball


package com.cmh.concurrent;

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

/**
 * 控制弹球移动
 *
 * Author: cmh
 * Date:2021/4/18 1:39 上午
 */
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 positionon
     */
    public Ellipse2D getShape() {
        return new Ellipse2D.Double(x, y, XSIZE, YSIZE);
    }
}

BallComponent

package com.cmh.concurrent;

import javax.swing.JPanel;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.ArrayList;
import java.util.List;

/**
 * 弹球面板类-填充颜色和大小
 *
 * Author: cmh
 * Date:2021/4/18 1:40 上午
 */
public class BallComponent extends JPanel {
    private static final int DEFAULT_WIDTH = 450;
    private static final int DEFAULT_HEIGHT = 350;

    /**
     * ? 这个是干嘛用的?为啥要存在List里面?
     */
    List<Ball> balls = new ArrayList<>();

    /**
     * Add a ball to the component
     */
    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) {
            System.out.println("List的size是:"+balls.size());
            g2.fill(b.getShape());
        }
    }

    public Dimension getPreferredSize() {
        return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT);
    }
}


2、有线程代码

package com.cmh.concurrent;

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

/**
 * Author: cmh
 * Date:2021/4/18 2:35 下午
 */
public class BounceThread {
    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            JFrame frame = new BounceFrame();
            frame.setTitle("BounceTread");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
        });
    }

    static class BounceFrame extends JFrame {
        private BallComponent comp;
        public static final int STEPS = 1000000;
        public static final int DELAY = 3;

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


        }

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

        public void addBall() {
            Ball ball = new Ball();
            comp.add(ball);
            Runnable runnable = () -> {
                try {
                    for (int i = 1; i <= STEPS; i++) {
                        ball.move(comp.getBounds());
//                        comp.repaint();
                        comp.paint(comp.getGraphics());
                        Thread.sleep(DELAY);
                    }
                } catch (InterruptedException interruptedException) {

                }
            };
            Thread thread = new Thread(runnable);// status:NEW
            thread.start();//status:RUNNABLE
        }
    }

    /**
     * 总结:
     * 1、多次连续点击start的时候,部分球就原地不动了,为什么?
     * 2、
     */
}

三、核心

1、控制球的移动
代码很简单,效果比较炫
2、画弹球

paintComponent()方法super.paintComponent(g);
这行代码去除了背景,否则每次移动的弹球轨迹都会展现出来,效果就像“贪吃蛇”了。


3、并发部分
没个弹球的位置移动都是一个独立的线程来控制

 public void addBall() {
            Ball ball = new Ball();
            comp.add(ball);
            Runnable runnable = () -> {
                try {
                    for (int i = 1; i <= STEPS; i++) {
                        ball.move(comp.getBounds());
                        comp.repaint();
                        Thread.sleep(DELAY);
                    }
                } catch (InterruptedException interruptedException) {

                }
            };
            Thread thread = new Thread(runnable);// status:NEW
            thread.start();//status:RUNNABLE
        }

好了,再会。

深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值