java实现多线程画图(线程进程区别、并发并行区别、java实现多线程画图等等知识)

  • Post author:
  • Post category:java




多线程基础知识



进程与线程

进程是资源分配的最小单位,线程是CPU调度的最小单位。做个简单的比喻:

进程=火车,

线程=车厢线程在进程下行进(单纯的车厢无法运行)

一个进程可以包含多个线程(一辆火车可以有多个车厢)

不同进程间数据很难共享(一辆火车上的乘客很难换到另外一辆火车,比如站点换乘)

同一进程下不同线程间数据很易共享(A车厢换到B车厢很容易)

进程要比线程消耗更多的计算机资源(采用多列火车相比多个车厢更耗资源)



并发与并行

并行:两个任务在同一时刻互不干扰的

同时

执行。如游泳赛道上不同道的选手

同时

在游泳。

Mon 06 06:00 12:00 06:00 Tue 07 06:00 12:00 06:00 Wed 08 任务1 任务2 进行中的任务 并行示意图

并发:同一段时间内两个任务发生,有前后顺序。如:2s内,裁判开枪,运动员跳入水中,这两个事件在极短时间内都发生了,但

不是同时

发生,是有先后的。

Mon 06 Mon 13 线程1 线程2 线程3 进行中的线程 并发示意图



画图面板设计

首先看一下效果,每次点击start可以画一条线,一条线还没有画完的时候,可以点击start再画一条,实现多线程画图的效果。

在这里插入图片描述

首先需要设计一个面板来显示画的图。下面是代码

使用JFrame画一个面板,设置好标题大小等信息后,新建一个按钮“Start”,把按钮加入面板,设置流式布局,但要每点击一次出现画图效果,我们还要使用监听器,并具体设计监听器的代码,编写我们想要的效果。

ButtonListener这个类就是我们要写画图效果的地方。画图必须要有画笔,我们要把JFrame中获取的画笔传给ButtonListener。

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;
public class UI {
    public static void main(String[] args) {
        UI ui  = new UI();
        ui.initUI();
    }
    public void initUI(){
        JFrame jf = new JFrame();
        jf.setTitle("ball game");
        jf.setSize(1100,1100);
        jf.setLocationRelativeTo(null);
        jf.setDefaultCloseOperation(3);
        jf.setLayout(new FlowLayout());
        JButton jb = new JButton("Start");
        jf.add(jb);
        jf.setVisible(true);
       ButtonListener listener =  new ButtonListener(jf.getGraphics());
        jb.addActionListener(listener);

    }
}



监听器设计

按钮对应的监听器是ActionListener接口,我们必须写一个类来继承这个接口,再重写里面的actionPerformed方法,在方法里写我们自己想要的效果。下面是代码。UI类中传过来的画笔赋给当前ButtonListener类的画笔,此时,如果我们直接在actionPerformed里设置循环写代码,会发现,必须等一条线画好了,才可以继续按按钮话第二条线,这不符合我们想多线程画图的需求,此时我们需要设计一个MyThread类,来开启多线程,实现并发画图。

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

public class ButtonListener implements ActionListener {
    private Graphics g;
    public ButtonListener(Graphics g) {
        this.g = g;
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        MyThread myThread  = new MyThread(g);
        myThread.start();
    }
}



线程类设计

下面是MyThread类的设计思路:首先继承Thread线程类,重写run方法,里面写我们想让该线程干的事情,但是记住再调用MyThread类时,

必须用start方法才可以实现多线程

。(也就是上面的 myThread.start();这一句代码)初始化一个画笔,用于传给ButtonListener的监听器方法,再按按钮时画图,因为要画多条线,每次就要随机一个起始横坐标点x,然后设置循环,不断画圆,每次y方向增加一个单位,连起来就是一条线的效果了。Thread.sleep(10);这条语句是为了设置线程休眠,让我们能清晰地看到计算机画圆的过程。注意,每次用这个方法是必须

捕获异常

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

public class MyThread extends Thread{
    private Graphics g ;
    private  int x,y=80,size = 50;


    public MyThread(Graphics g) {
        this.g = g;
        x = (int)(Math.random()*1100);
        System.out.println("x = "+x);
    }

    @Override
    public void run() {


        for (int i = 0; i < 1000; i++) {
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
//            g.drawImage(image.getImage(),x,y,null);
            g.fillOval(x,y++,50,50);
            System.out.println(x+"正在执行");
        }
    }
}



版权声明:本文为weixin_47814090原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。