Java 多线程

线程

概念

线程:程序执行的顺序流

多线程:多任务执行、多路径执行;可同时执行。

进程与线程区别

进程:资源分配最小值,每个进程都有独立的代码和数据空间(进程上下文)。

线程:cpu调度执行的最小单位,一个进程至少包含1~n个线程。

附:

多线程的优缺点

**优点:**资源利用率更好,效率高,性能高

**缺点:**程序设计复杂;有可能出现数据不安全情况

线程创建方式

1.继承Thread,重写run()+start()开启

2.实现Runnable接口,重写run()方法 + start() --> 推荐

3.实现juc包下Callable接口,重写call()方法 + 线程池方式

优点 :1、接口可以多实现,类只能单继承;

2、更好的实现资源的共享;

方法重写时的要求:

== 方法签名完全相同

<= 返回值类型,基本数据类型相同,引用数据类型重写方法<=被重写方法

>= 权限修饰符

异常 <= 重写方法上抛出的编译时异常<=被重写时抛出的==编译时异常==

多线程一些方法

sleep()

sleep : static void sleep(long millis) 参数为ms

线程休眠指定时间|ms|ms+ns

原理:会使线程进入到阻塞状态,阻塞指定时间接触之后恢复到就绪sleep休眠的过程中会让出cpu的资源,抱着对象的锁资源睡觉

作用 :1.模拟网络延迟 2.放大问题出现的可能性

yeild()

static void yield() 礼让线程

当一个线程执行yield方法,会让出cpu的资源同时恢复到就绪状态

join()

void join() 等待这个线程死亡。

void join(long millis) 此线程最多等待 millis毫秒。

void join(long millis, int nanos) 此线程最多等待 millis毫秒加上 nanos纳秒。

注意:当前线程如果被其他线程插队,当前线程就会进入到阻塞状态,等待插队线程执行完毕|等待指定时间接触阻塞先开启线程然后再插队;

getState()

获取线程状态(可获取的如下)

状态

解释

NEW -> 新生状态

尚未启动的线程处于此状态。

RUNNABLE ->就绪状态

在Java虚拟机中执行的线程处于此状态。

BLOCKED -> 等待对象锁资源的状态

被阻塞等待监视器锁定的线程处于此状态。

WAITING -> 阻塞状态 wait() join()...

无限期等待另一个线程执行特定操作的线程处于此状态。

TIMED_WAITING ->与时间相关的阻塞状态 sleep(ms),join(ms)...

正在等待另一个线程执行最多指定等待时间的操作的线程处于此状态。

TERMINATED -> 终止状态

已退出的线程处于此状态。

线程优先级

线程优先级 : Priority 1~10 了解

放大线程优先执行的概率

默认优先级 : 5

static int MAX_PRIORITY 线程可以拥有的最大优先级。

static int MIN_PRIORITY 线程可以拥有的最低优先级。

static int NORM_PRIORITY 分配给线程的默认优先级。

void setPriority(int newPriority) 更改此线程的优先级。

int getPriority() 返回此线程的优先级

守护线程

用户线程

创建线程时,默认为用户线程

如果程序执行存在多个线程,所有的用户线程全部执行完毕程序才会终止

守护线程

守护线程是来守护用户线程

当所有的用户线程全部执行完毕,守护线程无论是否执行完毕会自动终止执行

注意

垃圾回收机制是典型的守护线程 ;

先设置守护线程然后设置就绪start;

设置守护线程

			setDaemon(boolean)
				true --> 守护线程
				false --> 默认用户线程

interrupt()

void interrupt() 为线程添加中断标识。

boolean isInterrupted() 测试此线程是否已被中断,是否曾经调用过interrupt方法添加了中断标识,是返回true,不是返回false。

static boolean interrupted() 测试当前正在执行的线程是否已被中断,是否曾经调用过

interrupt方法添加了中断标识,是返回true,不是返回false。同时会复位标识

注意 :

sleep方法让一个线程处于指定时间的休眠状态时,如果有任何线程中断了当前线程,调用interrupt方法添加了中断标识,遇到InterruptedException - 。 抛出此异常时,将清除当前线程的中断状态 。

线程状态(5种)

新生状态 : new

就绪状态 : start 就会进入到就绪队列,等待cpu的调度

运行状态 : 处于就绪状态的线程一旦被cpu调度,就会进入到运行状态

**阻塞状态 :**如果一个线程执行了sleep(睡眠)、suspend(挂起)等方法,失去所占用资源之后,该线程就从运行状态进入阻塞状态。

**终止状态 :**一个运行状态的线程完成任务或者其他终止条件发生时


如何让一个线程进入到就绪状态 :

1.start

2.阻塞解除

3.yield

4.cpu调度切换


如何让一个线程进入阻塞状态 :

1.sleep

2.join

3.wait

4.IO


如何让一个线程进入终止状态 :

1.正常执行完毕

2.stop()不推荐使用

3.通过标识判断

题目

模拟12306抢票

模拟龟兔赛跑

人车共用街道

打印AB1CD2...

线程安全

概念

当多个线程同时操作同一份资源,才有可能出现线程不安全情况

同步锁

定义

		让多个线程排队执行重点代码(有可能操作数据不安全代码),达到数据安全

组成

		1.同步的代码段 : 排队执行的代码段
		2.条件多线程排队执行的条件 --> 对象锁(一个对象只有一把锁,多个线程之间获取对象锁,才有资格执行同步的代码段)

使用方式

==1.同步方法==

		方法上使用synchronized修饰 -->简单,但是有可能同步的代码范围太大,造成效率较低(方法体内部如果出现不需要排队执行的代码)
			判断方法体中所有的代码 是否都可以排队执行,是否会造成逻辑不正确
		同步的代码段 : 整个方法体

条件 :

成员方法 : this

静态方法 : 类的Class对象

==2.同步块==

		 复杂,颗粒度较细,更精确,相对可能效率较高
		synchronized(条件){
            排队执行的代码段;
        }

条件 : 类的Class对象|this|资源对象

			类的Class对象 : 每一个类都存在一个Class对象,在类加载到内部后就存在,并且独一份的

相当于锁了这个类的所有对象,在每个线程操作自己对象的情况下有可能操作效率较低情况,这种情况下不推荐锁类-->可以去锁this

线程通信

定义:

wait(),notify(),notifyAll()实现线程通信

来自于Object类,通过对象.wait()....进行调用

作用是用来协调多线程多共享数据存储问题,需要使用在同步环境下,否则会遇到异常java.lang.IllegalMonitorStateException

方法:

wait():

		等待,当前线程执行到对象.wait()会进入到与该对象相关的等待池中进行等待(等待状态,阻塞状态),等待指定时间|等待被唤醒

会让出cpu的资源同时释放对象的锁资源

sleep() :

		线程休眠,让出cpu的资源,但是不会释放对象的锁资源--> 抱着资源睡觉

notify() :

		唤醒处于该对象等待池中正在等待的线程,会恢复到就绪状态,cpu的调度与是否能够获取对象的锁,满足这两个条件线程才能继续执行

notifyAll() :

		唤醒所有正在等待的线程

案例:

红绿灯问题

通过信号灯法实现生产者消费者模式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值