java复盘,⑩多线程
2021/5/4 12:27:20
本文主要是介绍java复盘,⑩多线程,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
//mian方法是一个主线程,通过主线程,去调用别的线程
//怎么去确实这个程序是否是多线程呢?
//你可以用一条线,如果程序在运行的时候,能通过这条线穿起来的就是单线程
-
1.程序:程序存储在硬盘里面,包含可以执行的计算机指令(很多的exe文件,运行指令完成某种功能)和数据静态的实体(静态代码)
-
2.进程:指的是一个在内存中运行的程序,每一个程序都有一个独立的空间,一个应用程序可以同时运行多个
-
进程,进程也是程序的一次执行过程,是系统运行程序的一个基本单位,系统运行一个程序即是从一个进行的
-
创建、运行和消亡的过程。
-
3.线程:线程是进程中的一个执行单元,负责当前进程中的程序执行,一个进程至少包含一个线程,一个
-
进程中可以包含多个线程,这个应用程序就是多线程应用程序
-
4.多线程:在单个程序中同时运行多个线程完成不同的功能,叫做多线程
-
(1)用户想服务器发送了一个请求,服务获取请求并且根据请求响应结果,这就是一个线程
-
(2)客户端N个请求同时去请求服务器,这就是多线程
-
(3)线程有两种调度方式:抢占式调度和
-
分时调度:所有线程轮流使用cpu的使用权,平均分配每个线程占用cpu的时间,打饭排队的过程
-
抢占式调度:优先让优先级高的线程使用cup,java就是使用的抢占式,挂急诊,伤重的优先,其他的继续排队的过程
-
5.并发和并行
-
并发:一个处理器在同一时间内同时执行多个任务(一个人同时吃两个馒头),(//并发:指的是两个或多个事件在同一时间内发生,交替执行,不好掌控没法确定谁先抢占)
-
一个时间内有多个时间单位组成,所以说并发的多个任务在单位时间内不一定在同时进行
-
并行:多个处理器同一时刻同时处理多个不同的任务(两个人同时吃两个馒头)(//并行:指的是两个或多个事件在同一时刻发生)
-
这是真正同时执行的
-
显然,并行效率比并发效率高
-
6.为什么使用多线程?
-
提高CPU的一个计算能力,避免资源浪费
-
提高系统的一个响应速度
-
一直让cpu运行着
-
7.共享资源
-
允许多个不同的线程访问同一个资源,最好用实现的方式
-
8线程的分类(了解)
-
可以分为用户线程和守护线程
-
(1)用户线程:java创建的线程默认都是用户线程
-
(2)守护线程:后台运行的线程,用于提供后台的服务(gc)
-
区分:
-
如果进程中还有用户线程,进程是不会终止的
-
如果进程中只有守护线程,进程会终止
-
9.线程的生命周期,分为5个阶段
-
新建: 当一个Thread类或其子类的对象被声明并创建时,新生的线程对象处于新建状态
就绪:处于新建状态的线程被start()后,将进入线程队列等待CPU时间片,此时它已具备了运行的条件
运行:当就绪的线程被调度并获得处理器资源时,便进入运行状态, run()方法定义了线程的操作和功能
阻塞:在某种特殊情况下,被人为挂起或执行输入输出操作时,让出 CPU 并临时中止自己的执行,
进入阻塞状态,堵塞是相当于挂起,临时中止不再去抢了
注意:yield不是堵塞,他是是放再去抢
死亡:线程完成了它的全部工作或线程被提前强制性地中止
*/
/**
- 创建一个子线程,完成1-100之间的自然数的输出,同样主线程执行同样的操作
- 创建多线程的第一种方式:继承Thread类
- 1.继承Thread类
*2.重写run方法 ,线程中实际要执行的业务逻辑 - 3.创建子类对象
- 4.调用线程的start()方法
//1.创建一个类继承Thread
class SubThread extends Thread{
//2.重写run方法:线程中实际要执行的业务逻辑 public void run(){ for(int i=1;i<=100;i++){ //获取时此线程的名字//Thread.currentThread() System.out.println("子线程:"+i); } }
}
public class TestThread {
public static void main(String[] args) {
//3.创建一个子类对象 SubThread sub=new SubThread(); SubThread sub1=new SubThread(); //4.调用线程start()方法:启动此线程,调用相应的run方法 sub.start();
// sub.run();//这就不是一个多线程了,没有启动多线程
//创建一个线程
sub1.start();
for(int i=1;i<=100;i++){ System.out.println("主线程:"+i); } }
}
- Thread类常用的方法
- 1.void start(): 启动线程,并执行对象的run()方法
2.run(): 线程在被调度时执行的操作,子线程需要执行的代码放到run方法中
3.String getName(): 返回线程的名称
4.void setName(String name):设置该线程名称
5.static currentThread(): 返回当前线程
6.yield():调用了此方法的线程立马释放cpu资源执行权
(当一个线程使用了此方法后,就会把自己cup执行权释放,让给自己或着其他的线程
,这个让不是单纯让给别的线程,释放以后自己和别的线程再去抢cpu的执行权)
7.join():在线程1中调用线程2的join方法,表示执行到此方法后,线程1会进入一个阻塞(停止),
直到线程2执行完成以后,线程1在接着执行
8.sleep():让该线程休眠,以毫秒为单位
令当前活动线程在指定时间段内放弃对CPU控制,使其他线程有机会被执行,时间到后重排队。
抛出InterruptedException异常
9:isAlive():判断当前线程是否存活
10。线程通信的方法
11.设置优先级 :默认是5 最小值是1,最大值是10
getPriority():获取线程的优先级值
setPriority():设置线程的优先级
MAX_PRIORITY(10);
MIN _PRIORITY (1);
NORM_PRIORITY (5);
- 实现线程的第二种方式,
- 1.创建一个类实现Runnable接口
- 2.重写Runnable接口的run方法
- 3.创建一个实现Runnable接口实现类的对象
- 4.将实现类对象作为形参方式传递给Thread类的构造方法
- 5.调用start方法,启动线程,并且调用实现类的对象的run方法
- 继承方式vs实现的方式
- Thread implements Runnable
- 那个方式好?实现的方式优先于继承的方式
- (1)避免了java单继承的问题
- (2)如果多个线程要操作同一份资源(共享资源),实现的方式更加适合
class PrintNum implements Runnable{
//2.重写run方法 @Override public void run() { for(int i=1;i<=100;i++){ System.out.println(Thread.currentThread().getName()+":"+i); } }
}
public class TestThread2 {
public static void main(String[] args) { //创建一个实现类 PrintNum p = new PrintNum();
// p.start();会发现没有start方法
// p.run();这样写也不对,没有开启一个线程
//怎么启动一个线程呢?必须得调用start方法 Thread t = new Thread(p);/start方法是线程类Thread定义的方法 t.setName("子线程"); t.start();//启动一个线程,执行Thread对象生成的构造方法时的形参对象的run方法 //主线程 Thread.currentThread().setName("主线程"); for (int i = 1; i <= 100; i++) { System.out.println(Thread.currentThread().getName() + ":" + i); } }
-
线程通信的三个方法;必须使用在同步代码块或同步方法中
-
wait():等待,一旦一个线程执行wait方法,就相当于释放当前的锁
*notify()/notifyAll();唤醒wait的一个或者多个线程 -
死锁
不同的线程分别占用对方需要的同步资源不放弃,
都在等待对方放弃自己需要的同步资源,就形成了线程的死锁
两个人去餐馆吃饭,有一碗饭,只有一双筷子,一只筷子相当于一个锁,一人拿了一支,都不肯放手 -
*/
//在开发中注意代码的抒写,减少死锁 -
模拟火车站窗口售票,开启三个窗口同时售票,100张票
-
使用实现的方式实现
-
1.引起的问题:此线程是存在线程安全问题(错票、重票)
-
原因:由于一个线程在操作共享数据的过程中,未执行完毕,另外的线程此时也参与
-
进来了,导致共享数据出现线程安全问题
-
2.绝对线程安全问题:线程的同步机制
-
方式1: 同步代码块
-
synchronized (同步监视器){
// 需要被同步的代码;(为操作共享数据的代码)
}
1.共享数据:多个线程共同操作同一个数据 2.同步监视器:由一个对象(任何对象)来充当的,哪一个线程获得了此监视器,这个线程就 执行大括号里面的同步代码。可以理解为锁 要求:所有的线程必须共享一把锁 在实现的方式中,一般使用this来充当锁,但是在继承的实现中,不要用this
- 方式2:同步方法
- 将操作的共享代码的方法声明为synchronized,该方法就是一个同步方法,
- 保证其中一个线程执行该方法时,其他线程在外等待直到此线程执行完该方法,
- 同步方法的锁:谁调用我这个方法谁就是锁,this
static Object obj=new Object();//共享一把锁,锁可以是任何对象
这篇关于java复盘,⑩多线程的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-05-31全网首发第二弹!软考2024年5月《软件设计师》真题+解析+答案!(11-20题)
- 2024-05-31全网首发!软考2024年5月《软件设计师》真题+解析+答案!(21-30题)
- 2024-05-30【Java】百万数据excel导出功能如何实现
- 2024-05-30我们小公司,哪像华为一样,用得上IPD(集成产品开发)?
- 2024-05-30java excel上传--poi
- 2024-05-30安装笔记本应用商店的pycharm,再安排pandas等模块,说是没有打包工具?
- 2024-05-29java11新特性
- 2024-05-29哪些无用敏捷指标正在破坏敏捷转型?
- 2024-05-29鸿蒙原生应用再新丁!新华社 入局鸿蒙
- 2024-05-29设计模式 之 迭代器模式(Iterator)