Java多线程并发

目录

进程的概念

线程的概念

并发的概念

并行的概念

简单的实例应用


进程的概念

一个在内存中运行的应用程序。每个进程都有自己独立的一块内存空间,一个进程可以拥有多个线程,比如在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方法

 至此,我们就完成了多线程并发的初步学习。


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