Java学习不知道第几天之——线程

Thread 常用构造器

public Thread()

构建默认名称普通用户线程

public Thread(Runnable target)

构建依赖于Runnable接口实例的普通用户线程

public Thread(Runnable target,String name)

构建依赖于Runnable接口实例的普通用户线程并设置线程名称

多个线程共用同一个run()

继承Runnable接口

Thread.currentThread()//获取当前正在运行的线程

线程的休眠和吵醒

thread.sleep()

线程休眠,让出cpu内存

thread.interrupt()

打断线程当前状态,线程休眠进行打断,即结束当前线程休眠状态

线程联合

当前线程想要独占CPU资源

/*无限期等待当前线程执行结束*/
public final void join( ) throws InterruptedException


/*在millis毫秒内等待当前线程执行结束*/
public final void join( long millis ) throws InterruptedException


/*在mil毫秒和nano纳秒内等待当前线程执行结束*/
public final void join( long mil, int nano ) throws InterruptedException

/*Thread的静态本地方法,调用时将暂停当前正在运行的线程,与sleep0不同不需定时,也无需唤醒,影响作用正在瞬间暂停执行,却又迅速恢复,受此方法影响的状态不是中断而是RUNNABLE状态*/

Thread.yield()

线程之间的通信

在处理线程同步时,要做的第一件事就是要把修改数据的方法用关键字synchronized来修饰.一个方法使用关键synchronized修饰后,当一个线程A使用这个方法时,其他线程想使用这个方法时就必须等待,直到线程A使用完该方法.

同步代码块(synchronize修饰)

同步对象(synchronize修饰)

同步方法(synchronize修饰)

Java如何实现线程安全

synchronize的作用

Java多线程中唯一用来处理线程安全问题的语法糖,被Synchronized关键字所修饰代码中所有资源在同一时间只能被一个线程持有当前对象所访问,任何其他线程必需等待当前线程执行完所有Synchronized所限制的代码才能有机会获得执行此代码的机会,Synchronize成为唯一用来处理线
程同步安全的语法糖。

Java中的锁

同一时间只能有一个线程持有当前对象的锁,持有锁后,此对象不能被其他线程持有,对象锁的作用是保证线程同步的,是排斥锁。

监视器

 

重入

JVM规定,一个线程已获得一个对象的锁后,它可连续获得对象锁,而不必等待释放锁,此种行为被称作锁重入重入只针对当前拥有对象锁的线程而言,其他线程不可以重入。
JVM对于重入的现象对锁实施维护一个记数器行为每重入一次计数器增加1,如果为0则表示未锁定,其他线程可以在进入监视器后自由争夺锁。

同步当前对象

对象同步锁

①对共享对象的访问必须同步,叫做条件变量
②Java语言允许通过监视器使用条件变量实现线程同步
③监视器阻止两个线程同时访问同一个条件变量,它如同锁一样作用在数据上。

同步当前对象:

 

同步方法

方法同步锁

用synchronized来标识的方法为互斥方法。表明在任何给定的时候只能有一个线程可以执行该方
法(方法同步锁)。锁定的是方法的调用。同步方法会将方法内所有的代码都同步。同步方法锁定的是当前对象而不是方法

 

 同步线程的等待与唤醒

同步线程的等待

当前线程必须拥有监视器(有锁状态),才能执行等待命令,一旦进入等待状态即放弃当前监视器所有权(即释放锁),其他线程有权进入监视器获得所有权(即获得锁)。

等待时在监视器中进行等待,未离开监视器,只是放弃监视器所有权。(且不争夺监视器等待唤醒后重新争夺监视器所有权)

等待可能是无期限或者有期限的

其他线程可通过notify()或者notifyall()将处于等待状态的线程唤醒,

执行notify()或者notifyAll()的对象必须拥有监视器(有锁状态),

一旦发出notify()或者notifyAll()命令就会对等待状态的线程进行唤醒,

当前拥有监视器的对象不一定要在结束所有命令后才可对等待中的线程进行唤醒,在任何时候都可进行唤醒。

等待的线程不是立刻就醒来,醒来的时机是发出唤醒命令的线程退出监视器(即释放锁)其他线程才可以醒来

被唤醒的线程进入当前监视器等待队列中,并未退出监视器,争夺监视器(锁)的所有权。

等待的方法

public final void wait( ) throws InterruptedException

/*无限期等待,只有其他拥有监视器的线程通过notify()或者notifyAll()才可将其唤醒,醒来后也不一定能够获得监视器所有权,可能会一直处于等待状态*/


public final void wait(long mil) throws InterruptedException

/*mil表示等待时间,经过等待时间后可自动唤醒*/


public final void wait(long mi,int nano) throwsInterruptedException

/*在mil毫秒和nano纳秒内唤醒当前线程*/

同步线程的唤醒

只有当前线程放弃此对象监视器(即释放锁),才能继续执行被唤醒的线程。

必须是已经拥有监视器(有锁)的对象才有权利执行唤醒。

唤醒可以在拥有对象监视器的任何时期进行

被唤醒的线程真正醒来的时期,一定是执行唤醒操作的对象退出监视器后(释放锁后)

执行唤醒操作,并不意味着当前线程放弃监视器所有权(即并不意味着释放锁)

唤醒对象但并不放弃监视器所有权这种叫做 发信号并继续

唤醒的方法(必须拥有监视器所有权对象才可以进行唤醒)

public final void notify ( )
随机唤醒任意一个在此对象监视器上等待的线程,如果当前线程不是此对象监视器的拥有者则抛出llgalMonitorStateException

public final void notifyAll ( )
唤醒所有在此对象监视器上等待的线程,如果当前线程不是此对象监视器的拥有者则抛出llegalMonitorStateException

死锁

死锁是java多线程同步交互通信过程中某个锁无法得到最终释放的一种现象而形成死锁。

死锁通常更多的情况由于代码设计而发生,死锁发生JVM无法在运行期对死锁进行任何检查及处理,只能通过代码调试处理死锁

以下情况发生死锁
1、线程Left拥有对象obj锁LockO而等待线程Right拥有对象obj锁Lock2; Right则反之,从而相互等带,形成死锁
 


 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值