多线程之间实现通讯,join,yield,lock

目标:

    1.如何实现多线程之间的通讯

    2.了解wait,notify,notifyAll() 方法

    3.sleep 与 wait 的区别

    4.synchronized 与 lock 接口的区别i

    5.如何停止线程

    6.什么是守护线程

    7.join 方法

    8.优先级

    9.yield 方法

一、如何实现多线程之间的通讯

        1.什么是多线程之间的通讯?

        答:多线程之间的通讯,就是多个线程操作同一个全局变量时候,做的操作不同。如一个读,一个写。

       例子:

        如:一个线程做写入 用户信息操作,一个线程做读取用户信息操作。(生产消费模型)

        代码示例:

        创建实体类

        005308_tJ25_2886458.png

        创建连个线程

        005344_XoMg_2886458.png

        3.创建主线程

        005429_UI0U_2886458.png

 

        5.线程1做写的操作,线程2做读的操作。

        写操作线程

        010042_HDrd_2886458.png

        读操作线程

    010125_svAX_2886458.png

    创建线程看看效果!!

    010324_8nd1_2886458.png

效果:

    010631_Q19e_2886458.png

发生了线程安全问题!!!

   解决办法:

    在上一章节中讲到 用使用同步代码块或者锁来解决。

    010909_Soys_2886458.png

添加同步代码块或者锁来看看效果。

011228_SFgm_2886458.png

解决了数据冲突问题。那么下面我们如何做到一个线程写一个,另外一个线程读一个呢?

这里我们就用到wait,notify,notifyAll 这三个方法

二、wait,notify,notifyAll

    这三个方法分别有什么作用?

    wait(),notify(),notifyAll(),这三个方法是定义在object类里面的方法,用来控制线程的状态。这三个方法最终在jvm中调用是native 方法。

    wait():如果对象调用了次方法,那么就会把对象的控制权交出去,然后出于等待状态

    notify():如果对象调用了次方法,那么就会通知正在等待这个对象的控制权限可以继续运行,

    notifyAll():如果对象调用了这个方法,那么就会通知所有等待这个对象的控制权,继续运行。

   这里我们继续上面的例子:

    定义一个标识:

    012233_vpHq_2886458.png

写的线程

013253_spF8_2886458.png

读的线程:

012704_AYwK_2886458.png

运行结果:

013323_p2dD_2886458.png

这样线程之间的通讯就搞定了,生产者消费者模型也是基于此类的。

三、wait(),与sleep()的区别

    wait(): wait() 方法时object 类中的,如果对象调用了次方法,那么就会把对象的控制权交出去,然后出于等待状态

    sleep(): sleep() 方法是,Thread 类中的方法 ,次线程进入休眠状态,但是不会把对象的控制权交出去。处于休眠状态,即 把CPU 的使用权让出去给其他线程使用。

    总结:1.wait() 是object 类中的方法,而sleep()是Thread 类中的方法,

                2.wait()方法会释放锁,而sleep()不会释放锁

 四、lock 与synchronized 的区别

    1. 什么是lock?

      在 jdk1.5 之后,并发包中新增了 Lock 接口(以及相关实现类)用来实现锁功能,Lock 接口提供了与        synchronized 关键字类似的同步功能,但需要在使用时手动获取锁和释放锁。

       2.创建方法

        021027_lvKt_2886458.png 

021049_RyTU_2886458.png

021137_FpIC_2886458.png

 3.区别

    使用lock 可以手动获取锁,手动释放锁。

    synchroinzed 不能手动获取锁。释放锁。

 

五、如何停止线程

   

    1.  使用退出标志,使线程正常退出,也就是当run方法完成后线程终止。

    2.  使用stop方法强行终止线程(这个方法不推荐使用,因为stop和suspend、resume一样,也可能发生不可预料的结果)。

    3.  使用interrupt方法中断线程。

总结: stop 已经过时 强制停止 会造成线程安全问题, 一般使用interrupt方法来中断线程。

   六、守护线程

    Java中有两种线程,一种是用户线程,另一种是守护线程。

     当进程不存在或主线程停止,守护线程也会被停止。

     使用setDaemon(true)方法设置为守护线程

    1.为什么会出现守护线程?

       很多用户喜欢强退,因为线程是互补干扰的。如果主线程关闭了,那么其他线程还在继续跑怎么办?

    这就造成了守护线程。

    2.守护线程的作用

        当主线程停止时,守护线程也停止。

 七、join() 方法

        join()  方法,是让这个线程先执行。也就是让其他线程变为等待。

        join(3000) 意味着先执行三秒,让其他线程等待三秒。

    总结:保证线程的有序性!

   八、优先级

    现代操作系统基本采用时分的形式调度运行的线程,线程分配得到的时间片的多少决定了线程使用处理器资源的多少,也对应了线程优先级这个概念。在JAVA线程中,通过一个int priority来控制优先级,范围为1-10,其中10最高,默认值为5。下面是源码(基于1.8)中关于priority的一些量和方法。

    注意:设置了优先级,不代表每一次都被执行,只是CPU 会有限分配。

 九、Yield 方法

    

Thread.yield()方法的作用:暂停当前正在执行的线程,并执行其他线程。(可能没有效果)

yield()让当前正在运行的线程回到可运行状态,以允许具有相同优先级的其他线程获得运行的机会。因此,使用yield()的目的是让具有相同优先级的线程之间能够适当的轮换执行。但是,实际中无法保证yield()达到让步的目的,因为,让步的线程可能被线程调度程序再次选中。

结论:大多数情况下,yield()将导致线程从运行状态转到可运行状态,但有可能没有效果。

 

转载于:https://my.oschina.net/960823/blog/1521569

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值