java多线程

线程总结


线程的理解:程序要走的线路的整个过程,是程序执行流的最小单元。

程序可以由多个进程组成,进程有线程组成。如果没有用多线程,那该进程就一个主线程


程序也可以理解为一个进程,如果某个进程新建了多个线程,就会为进程开辟了多个个“线路”,但这个时候还没有开始走。只有当进程调用了 某个线程的启动,CPU才会在这条“线路”上走,这条“线路”才开始分配资源,尤其是栈内存空间。从线程的创建,到线程的启动,以及线程代码的执行,其中还包括wait、sleep、notify等方法导致执行权甚至是执行资格的丧失或是恢复,直到线程正常结束和非正常结束,这才是这条“线路”的整个“过程”,这也是线程真正的含义。


多线程安全问题:

原因:多个线程 操作 共享的数据 的代码不止一条。

解决:同步,synchronized、lock.lock()、lock.unlock()、readwriteLock.getReadLock.lock()、readwriteLock.getWriteLock.lock()...

synchronized:

用了同个锁,不管是不是同个方法 或者 同个同步块,都是同步的,都必须要等持有锁的对象执行完代码释放了锁  后面的线程才可以拿到锁 执行同个 或 不同的 被同步的代码。

同步函数锁的是this

静态函数锁的是该类的Class对象,也就是字节码,对于字节码的比较用 == 显得更专业

ReentrantLock:

和synchronized使用类似,lock方法相当于synchronized{,unlock方法相当于},注意最好将unlock放在finally里

ReentrantReadWriteLock

读和读之间即使上锁了也不会同步的,写锁上锁了 其他线程读和写都不能操作了

getReadLock.lock()、getReadLock.unlock()、getWriteLock.lock()、getWriteLock.unlock()


线程空间分配解析:

创建线程必然有上下文环境,这个上下文环境本省就是一个线程,暂且称之为主线程。

无论是主线程还是子线程1 2 3 之类的,java虚拟机都会为 每个线程 创建一个独立的 栈内存空间,然后方法入栈,临时变量表记录所有变量,PC记录方法走到哪一步。

线程是程序要走的 某一条线路的 整个过程,所以这个线程之间的 栈内存 空间是不会数据共享的,也就是run方法的局部变量是每个线程 私有的。

但是run方法的存在是有上下文的,这个上下文就是类,无论是runnable的实现类,还是runnable实现类Thread的子类,都是一个类,有类就会有成员变量,这些成员变量是共享的数据。

操作线程共享的数据 无论是基本数据变量还是引用变量,都是只有一份,有的指向了常量池、有的指向了堆内存、有的指向了方法区。

如果操作共享数据的代码不止一条,比如先读后写,在读完之后该线程失去了执行权,被其他线程操作了,这个时候就容易发生安全问题。


死锁:

在解决了线程安全的问题后要注意会不会发生死锁,我们是不希望发生死锁的,但要能判断出。

我们在实际应用中是永远也不会让我们去写 死锁程序的,但是面试的时候却会遇到


死锁产生的原因:同步中嵌套同步

同步中嵌套同步,并且持有的锁不一样,多个线程访问的时候就会有问题了。
比如线程1拿到了A锁,没有拿到B锁,线程2拿到了B锁,却没有拿到A锁,但是只有拿到自己想要拿的锁之后才能将代码执行完,才会释放已持有的锁,这就会死锁。
因此,

应避免嵌套同步

(如果同步代码中有同步代码,但是 却是同一个锁,本质上来说并没有嵌套,因为锁是一样的,

如果是同步代码块只要写一个就好了,但是如果是递归调用同步方法却是没法避免的,可这不算嵌套,可以和事务嵌套进行类比区分)

就算是非要嵌套,也不要嵌套多个,最多两个,并且锁的顺序不要颠倒。

比如各个同步块中都是先锁A,后锁B,那么多线程调用也不会出现死锁,

因为假如 线程1拿到A锁 或者 甚至拿到B锁的时候 都持有了A锁,线程2根本拿不到A锁 更加拿不到A锁住的同步代码中的B锁了,那么线程1也不会因拿不到B锁而堵塞

同样的道理,如果非要嵌套多层同步,必须要确保锁的顺序要一致,在各个方法中都必须一致

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值