- 注重版权,转载请注明原作者和原文链接
作者:码农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();
}
}
老铁,如果确实对你有帮助请点个免费的赞鼓励一下
白嫖不好,创作不易。各位的点赞就是我创作的最大动力,如果我有哪里写的不对,欢迎评论区留言进行指正,我们下篇文章见!