java-多线程

多线程

程序:本地磁盘rom当中可执行的文件,例如:class文件、exe、sh、bat脚本

进程
1. 可执行文件,程序执行进入内存,变成进程,一个进程可以拥有多个线程。
2. 进程仅仅是一个容器,包含了线程运行中所需要的数据结构等信息。一个进程创建时,操作系统会创建一个线程,这就是主线程,而其他的线程,却要主线程的代码来创建,也就是由程序员来创建。
3. 进程是程序一次执行的过程,或是正在运行的一个程序。是动态过程:它有自身的产生,存在和消亡的过程。

线程:进程实现或完成的各种各样的任务是线程。线程由进程创建,是进程的一个实体。

并发:同一时刻,多个任务交替执行,单核cpu实现的任务就是并发。

并行: 同一个时刻,多个任务同时执行。多核 cpu可以实现并行。

创建多线程的两种方式:

1.直接继承(extends)Thread类
start()启动线程 ,最终会执行run方法
run方法就是一个普通方法,没有真正启动一个线程,就会把run方法执行完毕,才向下执行;
说明:当main线程启动一个子线程,主线程不会阻塞,会继续执行。

2.实现接口(implement)Runnable的方式,建议使用2

​ suo suo = new suo();
​ Thread thread = new Thread(suo , “一部”);
​ Thread thread2 = new Thread(suo , “二部”);
​ thread.start();
​ thread2.start();

代理模式。在控制台输出

线程方法:
setName:设置线程名称,使之与参数name相同
getName:返回该线程的名称
start:使该线程开始执行;java虚拟机底层调用该线程的start0方法
run:调用线程对象run方法
setPriority:更改线程的优先级(0-10)默认为5
getPriority:获取线程的优先级
sleep:在指定毫秒数内让当前正在执行的线程休眠(暂停执行);线程的静态方法,使当前线程休眠
interrupt:中断线程,但是没有真正结束线程。所以一般用于中断正在休眠的线程。

yield:线程礼让。让出cpu。让其他线程执行,但礼让时间不确定,所以不一定礼让成功。
join:线程插队。t1 ,t2两个线程,要让t2插入到t1前面,就要在t1里面调用t2.join(),t2执行结束之后,t1才会继续执行

  		Runtime runtime = Runtime.getRuntime();
  	​	//获取当前电脑的CPU数量/核心数
  	​	int cpuNums = runtime.availableProcessors();

用户线程守护线程

用户线程:也叫工作线程,当线程的任务智兴万或通知方式结束。
守护线程:一般是为了工作线程服务,当所有的用户线程层结束,守护线程自动结束。常见的守护线程:垃圾回收机制。当主线程结束,子线程也不会结束。

/*如果希望当main线程结束后,子线程自动结束,只需要将子线程设置成守护线程即可守护线程,要在线程start之前设置。*/

myThread.setDaemon(true);//设置为守护线程
myThread.isDaemon();//判断是否是守护线程
myThread.start();

线程的生命周期
thread.state枚举表示了线程的几种状态:
new,尚未启动的线程处于此状态
runnable(又分为ready就绪状态,running 运行状态),在java虚拟机中执行的线程处于此状态,进入此状态不一定会立马执行
blocked,被阻塞等待监视器锁定的线程处于此状态
waiting,正在等待另一个线程执行待定动作的线程出于此状态
timed_waiting,正在等待另一个线程执行动作达到指定等待时间的线程处于此状态。
terminated,已退出的线程出于此状态

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UnhcebKB-1653201920461)(D:\笔记\work\线程状态.png)]

线程同步机制synchronized

1.在多线程编程中,一些敏感数据不允许被多个线程同时访问,此时就使用同步访问技术,保证数据在任何同一时刻,最多有一个线程被访问,以保证数据的完整性。

同步的具体方法:

1.同步代码块:synchronized(对象){//得到对象的锁,才能操作同步代码、、需要被同步代码}

2.synchronized还可以放在方法中声明,表示整个方法-为同步方法

public synchronized void m (String name){表示同一时间只能有一个线程访问该方法}

互斥锁

基本介绍:
1.引入对象的互斥锁的概念,来保证共享数据操作的完整性。
2.每个对象对应一个可称为“互斥锁”的标记,此标记用来保证在任一时刻能有一个线程访问该对象。
3.关键字synchronized来与对象的互斥锁相互联系。当某个对象用synchronized修饰,表名该对象在任一时刻只能由一个线程访问。
4.同步的局限性:导致程序的执行速度变慢
5.同步方法(非静态)的锁是this,也可能是其他对象(要求是同一对象)
6.同步方法(静态)的锁是当前类本身

死锁

多个线程占用了对方的资源

public static void main(String[] args) {
//模拟死锁现象,尽量避免死锁
deadDemo deadDemoA = new deadDemo(true);
deadDemoA.setName(“线程A”);
deadDemo deadDemoB = new deadDemo(false);
deadDemoB.setName(“线程B”);
deadDemoA.start();
deadDemoB.start();
}

class deadDemo extends Thread{
static Object o1 = new Object();
static Object o2 = new Object();
boolean flag ;
public deadDemo(boolean flag) {
this.flag=flag;
}
public void run() {
/*业务逻辑分析

如果flag为T ,线程A就会先得到/持有o1对象锁,然后尝试去获取o2对象锁
如果线程A得不到o2对象锁,就会Blocked

如果flag为F ,线程B就会先得到/持有o2对象锁,然后尝试去获取o1对象锁
如果线程A得不到o1对象锁,就会Blocked

*/
if(flag) {
synchronized (o1) {//对象互斥锁,下面是同步代码
System.out.println(Thread.currentThread().getName()+“进入1”);
synchronized (o2) {//获得哦对象的监视权
System.out.println(Thread.currentThread().getName()+“进入2”);
}
}
}else {
synchronized (o2) {//对象互斥锁,下面是同步代码
System.out.println(Thread.currentThread().getName()+“进入3”);
synchronized (o1) {//获得哦对象的监视权
System.out.println(Thread.currentThread().getName()+“进入4”);
}
}
}
}
}

释放锁

1.当前线程的同步方法,同步代码执行结束
2.当前线程在同步代码块,同步方法中遇到break、return
3当前线程在同步代码块,同步方法中出现了未处理的Error或exception,导致异常结束
4.当前线程在同步代码块,同步方法中执行了线程对象的wait()方法,当前线程暂停,并释放锁

不会释放锁

1.线程执行同步代码块或同步方法是,程序调用Thread.sleep(),Thread.yirld()方法暂停当前线程的执行,不会释放锁
2.线程执行同步代码块时,其他线程调用了该线程的suspend()方法将该线程挂起,该线程不会释放锁

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值