谈谈多线程和进程,附上例题讲解

  • 注重版权,转载请注明原作者和原文链接
    作者:码农BookSea
    原文链接:https://editor.csdn.net/md?articleId=105927139

本人刚写博客不久,是个新人,望大家能给予一些鼓励。 您的一个赞或者是评论区的一句话都将是对我最大的激励。
在这里插入图片描述


1.线程和进程的区别

进程:进程是资源分配的最小单位
线程:程序执行的最小单位

计算级执行程序的时候,会创建相应的进程,进行资源分配的时候,是以进程为单位进行相应的分配
每个进程都有相应的线程,再执行程序时,实际上是执行相应的一些列线程

地址空间:进程是有自己独立的地址空间,每次启动一个线程,都会分配对应的地址空间,来处理数据。线程是没有独立空间的,可以共享进程的地址空间

资源拥有
进程之间的资源是互相独立的,同一个进程内的线程是可以共享本进程内的资源

执行过程;每个独立的进程有一个程序运行的入口,我们回去顺序的执行序列和程序入口。线程不能独立执行,必须要依存再应用程序中,由应用程序提供多个线程执行控制

引入例子:比如说,A在一边在跟男朋友聊天,一边在跟我们上课。两个动作同时进行,一个应用程序就是一个可执行文件,里面包含了一个或者多个线程,一个或者多个线程中又包括了一个或者多个的进程

Window中的应用程序(软件运行)会产生线程(一个应用程序可以对应多个线程)->
进程

程序中使用多个线程(并发),效率会提升,线程是我们可以控制程序中的最小的执行单位,我们的多线程其实就是多个线程在进程里面去抢占资源

例子:A昨天早上起床(1h)-》洗漱(0.25h)-》吃早饭(0.25h)-》上课(8h)-》做作业(1h)-》打游戏(2h)-》聊天(6h)-》睡觉 。。。每次都是按照顺序执行,这个称为单线程
B:上课的时候在撩C-》做作业的时候也在撩C,在做一个动作的时候,同时也会在做另一个动作,那么这个就称为多线程

2.具体问题;

两个无限执行的循环
在这里插入图片描述

3.线程运行状态

在这里插入图片描述

4.Java种实现线程的方式

1使用Thread类
在这里插入图片描述
在这里插入图片描述

启动线程,调用的是start方法而不是run方法,start方法会调用start0,start0是一个native方法,JVM会自动执行

如果我们直接调用了start方法,线程就处于运行状态么?
先进入就绪状态,如果JVM分配了资源,则进入运行状态,如没有分配到资源则处于就绪状态 示例如下:

package com.etc.thread;

public class Thread01 extends Thread {

	
	public void run() {
		for(;1==1;) {
			try {
				sleep(500);//休眠
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println("线程001");
		}
	}
	
}
package com.etc.thread;

public class Thread02 extends Thread {

	
	public void run() {
		for(;1==1;) {
				try {
					sleep(1000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			System.out.println("线程002");
		}
	}
	
}
package com.etc.thread;

public class TestThread {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Thread01 th1=new  Thread01();
		Thread02 th2=new  Thread02();
		
		th1.start();
		th2.start();
	}

}

sleep用法
sleep(500)//sleep里面存的是时间,单位是毫秒,作用是将当前线程休眠指定的时长

2 使用Runnable实现线程
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3 使用callable实现线程
在这里插入图片描述

该接口下call方法有返回值
应用场景:
1:有返回结果,在某个线程的方法执行完成之后,需要告知调用者,结束了,例如我们想知道线程种代码的执行效率
2;面试:通过实现Callable接口,重写call方法,调用用到FutureTask

在这里插入图片描述

在这里插入图片描述

4 .FutureTask在这里插入图片描述

阻塞

堵车;下水道堵了

泡茶案例
两个步骤:烧水(10s)-洗杯子(5个杯子,一个位子2s)(按照顺序去执行) 20

两个步骤:烧水(10s)-洗杯子(5个杯子,一个位子2s)(两个线程并行执行)10

5. Thread和Runnable的区别和联系

1、Thread是一个类,Runnable是一个接口
2、Thread类实现了Runnable接口,重写了run方法
3、Runnable是一个接口,定义一个类实现接口的同时还可以继承其他类;
4、Runnable适合多个相同的程序代码的线程去处理同一个资源,代码可以被多个线程共享

6. 线程生命周期(必须要会描述)

在这里插入图片描述

新线程:当我们使用new关键字创建线程对象实例,那这个适合它只是作为一个对象存在,JVM没有为他分配CPU资源,

就绪状态:处于创建中的线程调用start方法将线程的状态转化为就绪状态,当前状态已经得到了其他的系统资源,在等待CPU资源

运行状态:就绪状态得到CPU资源后进入运行状态,执行run【call】方法中的代码段

等待/阻塞:线程运行的过程中被剥夺资源或则和我们在等待某些事件,这个就进入等待/阻塞状态,如supend()、sleep()被调用,或者线程使用wait()方法来等待条件变量,这个适合线程会释放所有的资源,但是并不释放锁,所以很容易引起死锁知道程序调用resume()方法回复线程运行。等待事件结束后或者得足够的资源就进入就绪态

死亡状态:当线程运行结束【正常结束】由JVM收回线程所占的资源

6 线程数据共享

练习:
要有5个售票点,用同一份数据,数据保持一致100张
使用Thread和Runnable两种方式完成

Synchronized

在这里插入图片描述
在这里插入图片描述

以上代码表示,当我们某个线程在使用这个方法的时候,其他线程无法使用当前方法,相当于给这个方法上了一个锁

join方法

Join用法

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

如上使用join()不传参时我们会先执行调用join的线程,只有在join的线程执行完了之后才会执行其他线程

在这里插入图片描述

如果join方法后面有传参,那么表示我们其他线程需要等待当前线程XX毫米,在等待完这个时长之后,其他线程就会开始执行

在这里插入图片描述

如上所示,join如果在start的前面将会失效,此时线程还未启动,此时使用join就不会有任何效果

t1调用了join方法,如果t1在规定的等待时间之前就完成了线程的运行,那么我们的其他线程就可以不用继续等待,可以直接进行线程的运行

7.线程同步和通信

创建一个用户类需要有名字,性别,还有showPerson方法(展示用户信息)、setPerson方法(将存入的用户信息替换)

创建一个线程类,修改用户信息。死循环一直去修改用户信息,如果是奇数就存一个对象,如果是偶数就存另一个对象

创建第二个线程类。一直去循环输出用户的信息,。
创建一个测试类。执行我们的两个线程

package com.etc.person;
//用户类
public class Person {

	private String name;
	private String sex;
	
	
	public Person() {
		super();
	}
	public Person(String name, String sex) {
		super();
		this.name = name;
		this.sex = sex;
	}
	
	/**
	 * 获取对象信息
	 */
	public void showPerson() {
		System.out.println(this.name+","+this.sex);
	}
	
	public void setPerson(String name,String sex) {
		this.name = name;
		this.sex = sex;
	}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
}
package com.etc.person;

import java.util.Random;

public class ModifyPerson implements Runnable{

	private Person person;
	private int n;
	
	
	
	public ModifyPerson(Person person) {
		super();
		this.person = person;
	}



	@Override
	public void run() {
		while(true) {
			//随机数去实例不同的用户去赋值
			n=new Random().nextInt(100);
			if(n%2==0) {
				person.setPerson("A", "男");
			}else {
				person.setPerson("B", "女");
			}
			
		}
	}

}
package com.etc.person;

public class ShowPerson implements Runnable{

	private Person person;
	
	public ShowPerson(Person person) {
		super();
		this.person = person;
	}
	@Override
	public void run() {
		
		while(true) {
			person.showPerson();
		}
		
	}

}
package com.etc.person;

public class Test {

	public static void main(String[] args) {
		//创建Person对象
		Person person=new Person();
		//修改线程对象
		ModifyPerson md=new ModifyPerson(person);
		//显示用户信息线程对象
		ShowPerson sp=new ShowPerson(person);
		
		Thread th1=new Thread(md);
		th1.start();
		new Thread(sp).start();
	}
	
}

老铁,如果确实对你有帮助请点个免费的赞鼓励一下

白嫖不好,创作不易。各位的点赞就是我创作的最大动力,如果我有哪里写的不对,欢迎评论区留言进行指正,我们下篇文章见!
在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章