目录
进程的概念
一个在内存中运行的应用程序。每个进程都有自己独立的一块内存空间,一个进程可以拥有多个线程,比如在windows中,一个运行的xx.exe就是一个进程
线程的概念
进程中的一个执行任务(控制单元),负责当前进程中程序的执行。一个进程至少有一个线程,也可以拥有多个线程,多个线程也可以共享数据。
我们可以在windows中的任务管理器看到,我们的CPU在处理中,进程就200多个,但是线程却拥有4000多个,从数量上我们就可以看出。
在我的《深入了解String常量池》中提到过,Java中的内存模型:JVM虚拟机,拥有堆和栈两个模块
堆:共享区 , 栈:线程私有的
进程和线程总结
根本区别:进程是操作系统资源分配的基本单位,而线程是处理器任务调度和执行的基本单位。
影响关系:一个进程崩溃后,在保护模式下不会对其他进程产生影响,但是如果一个线程崩溃整个进程都会死掉,所以说多进程比多线程更加健壮。
并发的概念
并发的实质是一个物理CPU(也可以多个物理CPU)在若干道程序之间多路复用,并发性是对有限物理资源强制使多用户共享以提高效率。
并行的概念
并行是指两个或者两个以上事件或者活动在同一时刻发生。在多道程序环境下,并行性使多个程序在同一时刻下可在不同的CPU上同时执行。
打个比方,并发,就像一个人(cpu)喂2个孩子(程序)吃饭,轮换着每人喂一口,表面上两个孩子都在吃饭。并行,就是2个人喂2个孩子,两个孩子也同时在吃饭。
简单的实例应用
我们就写一个移动的小球,我们肯定需要写一个DrawUI界面类,然后写一个动作监听器,当我们去点击界面上的按钮,它就开始画移动的小球。
如果我们只是简单是这样去做,在ActionListner的方法中去写
public class BtnListener implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
//在这里我们就去画移动的小球
}
}
这里我不把代码放下去,下面我会把正确的代码放上,如果按照上面这样做,我们会发现在小球画的时候我们进行不了任何操作,也不能关闭窗口。这是为什么呢?这就是所谓的单线程,如果我们的界面是一个进程,那么监听器的Graphics画笔就是一个线程,直接影响着我们的界面。
这个时候我们需要去一个线程类MyThread去继承Thread,然后去重写Thread的方法,启动线程时调用的方法。
DrawUI(主界面)
import java.awt.FlowLayout;
import java.awt.Graphics;
import javax.swing.JButton;
import javax.swing.JFrame;
public class DrawUI {
public void initUI() {
JFrame jf = new JFrame();
jf.setTitle("多线程并发");
jf.setSize(900,700);
jf.setLocationRelativeTo(null);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
FlowLayout fl = new FlowLayout();
jf.setLayout(fl);
JButton btn = new JButton("启动");
jf.add(btn);
jf.setVisible(true);
//绑定监听器
Graphics g = jf.getGraphics();
BtnListener listener = new BtnListener(g);
btn.addActionListener(listener);
}
public static void main(String[] args) {
DrawUI du = new DrawUI();
du.initUI();
}
}
BtnListener(监听器)
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class BtnListener implements ActionListener{
private Graphics g;
//初始化属性
public BtnListener(Graphics g) {
this.g = g;
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
//创建线程对象
MyThread mt = new MyThread(g);
//启动线程
mt.start();
}
}
MyTread(线程类)
import java.awt.Graphics;
import javax.swing.ImageIcon;
public class MyThread extends Thread{
private Graphics g;
private int x,y = 80,size = 50;
private ImageIcon image;
//初始化画笔对象
public MyThread(Graphics g) {
this.g = g;
x = (int)(Math.random()*800);
System.out.println("x = "+x);
//加载图片
//image = new ImageIcon("C:\\Users\\TZH\\Desktop\\微信图片_20210528181150.jpg");
}
//重写run 方法 :启动线程时调用的方法
public void run() {
for(int i =0;i<1000;i++) {
//延时
try {
Thread.sleep(40);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//绘制图片
//g.drawImage(image.getImage(), x, y, null);
//绘制运动小球
g.fillOval(x, y++, size, size);
}
}
}
当我们去运行这个程序时,就可以多次点击启动按钮,这是每一个在移动的小球都可以看做一个线程,他们之间互不干扰,却又共用着run方法
至此,我们就完成了多线程并发的初步学习。