说说java线程栈_Java-多线程

多线程

什么是线程和进程?

进程是系统运行程序的基本单位,在Java中启动一个main函数就是启动一个JVM进程,main函数所在的线程叫主线程.

线程是一个比进程还小的执行单位,一个进程可以产生多个线程.

总结 : 进程间是互相独立的,线程间是共享进程的空间,所以线程会有并发问题.

JVM

运行时数据区域

线程私有 : 程序计数器,虚拟机栈,本地方法栈

线程共享 : 堆,方法区,直接内存

程序计数器

主要有2个作用:

1. 字节码解释器通过改变程序计数器来决定下一条指令,从而控制代码流程.

2. 多线程情况下,程序计数器用来记录当前线程执行的位置,当线程切换回来的时候可以继续之前的流程,所以程序计数器是私有的.

Java 虚拟机栈

线程私有,Java内存大致可以分为堆区和栈区,栈区指的就是虚拟机栈,一般用来局部变量.

虚拟机栈可以出现的异常:

1. StackOverFlowError 当前线程请求栈的深度超过了虚拟机栈的最大深度.

2. OutOfMemoryError 当请求栈时,内存用完了且无法拓展时.

本地方法栈

线程私有,和虚拟机栈类似,区别是主要为 Native 方法服务.

虚拟机管理的内存中最大的一块,线程共享.垃圾回收管理的主要区域,所以也成为GC堆.几乎所有的对象实例以及数组都在这分配内存.

方法区

线程共享,主要存放被虚拟机加载的类的信息,常量,静态变量等.

多线程

虚拟机栈和本地⽅法栈为什么是私有的?

这两个栈都是用来存放局部变量的,所以私有是为了防止别的线程访问到当前线程的局部变量.

说说并发与并⾏的区别?

并发:一段时间内,多个任务都在执行.(单位时间内,只有一个任务在执行.)

并行:单位时间内,多个任务同时执行.

什么是上下⽂切换?

当一个线程的时间片用完的时候就会变成就绪态,让其他线程使用,这个过程就是一次上下文切换.

什么是线程死锁?如何避免死锁?

线程1拥有资源A,线程2拥有资源B,此时线程1去申请资源B,由于B已经被线程2持有,所以线程1进入阻塞等待状态,并且不会主动释放所持有的资源A,这就叫死锁.

如何避免线程死锁?

产生死锁的条件:

互斥条件 : 该资源某一时刻只能被一个线程所持有.

请求与保持条件 : 进程因为请求资源而阻塞时,已持有的资源保持不放.

不剥夺条件 : 线程所持有的资源除非自己主动释放,否则一直持有,其他线程无法强行剥夺.

循环等待条件 : 多个线程形成一个资源循环等待环.

避免死锁,破坏条件:

破坏互斥条件 : 无法破坏,因为锁的本意就是让资源在一段时间内只能被一个线程所持有.

破坏请求与保持条件 : 一次性申请所有资源.

破坏不剥夺条件 : 当线程申请资源失败的时候,释放自己所持有的资源.

破坏循环等待条件 : 按顺序申请资源.

sleep() ⽅法和 wait() ⽅法区别?

sleep不会释放锁,wait会释放锁.

都可以暂停线程.

wait调用后不会自动苏醒,需要别的线程调用notify()唤醒,但是可以使用wait(long timeout)超时自动苏醒.

为什么我们调⽤ start() ⽅法时会执⾏ run() ⽅法,为什么我们不能直接调⽤ run() ⽅法?

调用start()时,会启动一个线程,当线程获得CPU时间时执行run()里面的内容;直接调用run(),会把run()当初main()下的一个普通方法去执行.

synchronized关键字最主要的三种使⽤⽅式?

修饰实例(普通)方法 : 给当前实例对象加锁.

//假设 Demo 类的 demo() 被 synchronized 修饰

//例1 : 线程1,2抢占的是同一把锁,只能有一个线程持有.

public static void main(String[] args) {

Demo demo = new Demo();

Thread thread1 = new Thread(new MyThread(demo));

Thread thread2 = new Thread(new MyThread(demo));

thread1.start();

thread2.start();

}

//例2 : 线程1,2抢占的是两把锁

public static void main(String[] args) {

Demo demo1 = new Demo();

Demo demo2 = new Demo();

Thread thread1 = new Thread(new MyThread(demo1));

Thread thread2 = new Thread(new MyThread(demo2));

thread1.start();

thread2.start();

}

修饰静态方法 : 给当前类加锁,作用于类的所有实例对象.

修饰静态方法后上面不论是例1还是例2都是抢占一个锁.

修饰代码块 : 给指定对象加锁.

synchronized 关键字的底层原理?

synchronized 关键字属于JVM层面.

通过查看字节码信息可以发现, synchronized 锁定代码的前后分别是 monitorenter 和 monitorexit ;当执行 monitorenter 时,线程去尝试获取锁(monitor,它存在于每个Java对象的头部,

所以Java对象都可以作为锁.),当计数器为0时获取成功,然后将计数器加1;执行 monitorexit 时,计数器减一. 如果锁获取失败,那么当前线程就一直等待,直到锁被另一个线程释放.

标签:Java,Thread,Demo,虚拟机,死锁,线程,new,多线程

来源: https://www.cnblogs.com/qifengle1412/p/12885440.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值