java多线程(三)线程间通信

java多线程(三)线程间通信

等待,通知机制
* 等待:wait()方法可以使当前执行代码的线程进行等待,在调用wait()方法前,线程必须获得该对象的对象级别锁,即只能在同步方法或同步块中调用wait()方法。在执行wait(0方法之后,当前线程释放锁。在从wait()方法返回前,线程与其他线程竞争重新获取锁。如果没有获取,则会产生异常。
* 通知:notify()方法,只能在同步方法或同步块中调用notify()方法,线程必须获得该对象的对象级别锁。如果在调用notify()方法时没有获取对象级别锁,则会产生异常。当notify()方法被调用并执行完毕之后,处于wait状态的线程才可以获取对象级别锁。

方法wait()锁释放与notify()锁不释放
* 当方法wait()被执行完后,锁被自动释放,但执行完notify()方法,锁却不自动释放。
* 当方法notify()被执行完后,锁不会立即释放,而是要将包含notify()方法在内的所有代码都执行完之后才会释放锁。

notify()方法的特性
* notify()方法只随机唤醒一个处于wait()状态的线程。

wait(long)
* 此方法包含一个时间参数,功能是等待某一时间内是否有线程对锁(因为wait()方法必须在同步方法或者同步代码块中被调用)进行唤醒,如果超过这个时间则自动唤醒。

假死
* “假死的现象其实就是 ”线程进入WAITING等待状态。如果全部线程都进入到WAITING状态,则程序就不执行任何业务了,整个项目呈停止状态。
* 出现假死的主要原因:(在生产——消费模式中),同类连续唤醒同类。

/**
 * 生产者
 * Created by lx on 2017/4/7.
 */
public class P {

    private String lock;

    public P(String lock){

        this.lock=lock;

    }

    public void setValue(){

        try{
            synchronized (lock) {
                while (!ValueObject.value.equals("")) {
                    System.out.println("生产者" + Thread.currentThread().getName() + "WAITING了#");
                    lock.wait();
                }

                System.out.println("生产者" + Thread.currentThread().getName() + "RUNNABLE");
                String value = System.currentTimeMillis() + "_" + System.nanoTime();
                ValueObject.value = value;
                lock.notify();
            }
        }catch (InterruptedException e){
            e.printStackTrace();
        }

    }

}

/**
 * 消费者
 * Created by lx on 2017/4/7.
 */
public class C {

    private String lock;

    public C(String lock){

        this.lock=lock;

    }

    public void getValue(){

        try{

            synchronized (lock){

                while(ValueObject.value.equals("")){

                    System.out.println("消费者"+Thread.currentThread().getName()+"WAITING#");
                    lock.wait();

                }

                System.out.println("消费者"+Thread.currentThread().getName()+"RUNNABLE了");

                ValueObject.value="";

                lock.notify();

            }

        }catch (InterruptedException e){
            e.printStackTrace();
        }

    }

}
/**
 * 生产者线程
 * Created by lx on 2017/4/7.
 */
public class ThreadP extends Thread {

    private P p;

    public ThreadP(P p){
        this.p=p;
    }

    @Override
    public void run() {
        super.run();
        while(true){
            p.setValue();
        }
    }
}
/**
 * 消费者线程
 * Created by lx on 2017/4/7.
 */
public class ThreadC extends Thread {
    private C c;

    public ThreadC(C c){
        this.c=c;
    }

    @Override
    public void run() {
        super.run();
        while(true){
            c.getValue();
        }
    }
}

/**
 * 变量
 * Created by lx on 2017/4/7.
 */
public class ValueObject {

    public static String value="";

}

/**
 * 测试类
 * Created by lx on 2017/4/7.
 */
public class Launch {

    public  static void main(String []args){

        String lock = new  String("") ;

        P p=new P (lock);
        C c=new C(lock);

        ThreadP[] pThread=new ThreadP[2];
        ThreadC[] cThread=new ThreadC[2];

        for(int i=0;i<2;i++){
            pThread[i]=new ThreadP(p);
            cThread[i]=new ThreadC(c);
            pThread[i].setName("生产者"+(i+1));
            cThread[i].setName("消费者"+(i+1));
            pThread[i].start();
            cThread[i].start();
        }

        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        Thread[] threadArray=new Thread[Thread.currentThread().getThreadGroup().activeCount()];
        Thread.currentThread().getThreadGroup().enumerate(threadArray);

        for(int i=0;i<threadArray.length;i++){
            System.out.println(threadArray[i].getName()+"  "+threadArray[i].getState());
        }

    }

}

运行的结果为:

生产者生产者1RUNNABLE
生产者生产者1WAITING了#
消费者消费者1RUNNABLE了
消费者消费者1WAITING#
生产者生产者1RUNNABLE
生产者生产者1WAITING了#
消费者消费者1RUNNABLE了
消费者消费者1WAITING#
生产者生产者1RUNNABLE
消费者消费者1RUNNABLE了
消费者消费者1WAITING#
生产者生产者1RUNNABLE
消费者消费者1RUNNABLE了
消费者消费者1WAITING#
生产者生产者1RUNNABLE
生产者生产者1WAITING了#
消费者消费者1RUNNABLE了
消费者消费者1WAITING#
生产者生产者1RUNNABLE
生产者生产者1WAITING了#
消费者消费者1RUNNABLE了
消费者消费者1WAITING#
生产者生产者1RUNNABLE
生产者生产者1WAITING了#
消费者消费者1RUNNABLE了
消费者消费者1WAITING#
生产者生产者1RUNNABLE
生产者生产者1WAITING了#
消费者消费者1RUNNABLE了
消费者消费者1WAITING#
生产者生产者1RUNNABLE
生产者生产者1WAITING了#
消费者消费者1RUNNABLE了
消费者消费者1WAITING#
生产者生产者1RUNNABLE
生产者生产者1WAITING了#
消费者消费者1RUNNABLE了
消费者消费者1WAITING#
生产者生产者1RUNNABLE
生产者生产者1WAITING了#
消费者消费者1RUNNABLE了
消费者消费者1WAITING#
生产者生产者1RUNNABLE
生产者生产者1WAITING了#
消费者消费者1RUNNABLE了
消费者消费者1WAITING#
生产者生产者1RUNNABLE
生产者生产者1WAITING了#
消费者消费者1RUNNABLE了
消费者消费者1WAITING#
生产者生产者1RUNNABLE
生产者生产者1WAITING了#
消费者消费者1RUNNABLE了
消费者消费者1WAITING#
生产者生产者1RUNNABLE
生产者生产者1WAITING了#
消费者消费者1RUNNABLE了
消费者消费者1WAITING#
生产者生产者1RUNNABLE
生产者生产者1WAITING了#
消费者消费者1RUNNABLE了
消费者消费者1WAITING#
生产者生产者1RUNNABLE
生产者生产者1WAITING了#
消费者消费者1RUNNABLE了
消费者消费者1WAITING#
生产者生产者1RUNNABLE
生产者生产者1WAITING了#
消费者消费者1RUNNABLE了
消费者消费者1WAITING#
生产者生产者1RUNNABLE
生产者生产者1WAITING了#
消费者消费者1RUNNABLE了
消费者消费者1WAITING#
生产者生产者1RUNNABLE
生产者生产者1WAITING了#
消费者消费者1RUNNABLE了
消费者消费者1WAITING#
生产者生产者1RUNNABLE
生产者生产者1WAITING了#
消费者消费者1RUNNABLE了
消费者消费者1WAITING#
生产者生产者1RUNNABLE
生产者生产者1WAITING了#
消费者消费者1RUNNABLE了
消费者消费者1WAITING#
生产者生产者1RUNNABLE
生产者生产者1WAITING了#
消费者消费者1RUNNABLE了
消费者消费者1WAITING#
生产者生产者1RUNNABLE
生产者生产者1WAITING了#
消费者消费者1RUNNABLE了
消费者消费者1WAITING#
生产者生产者1RUNNABLE
生产者生产者1WAITING了#
消费者消费者1RUNNABLE了
消费者消费者1WAITING#
生产者生产者1RUNNABLE
生产者生产者1WAITING了#
消费者消费者1RUNNABLE了
消费者消费者1WAITING#
生产者生产者1RUNNABLE
生产者生产者1WAITING了#
消费者消费者1RUNNABLE了
消费者消费者1WAITING#
生产者生产者1RUNNABLE
生产者生产者1WAITING了#
消费者消费者1RUNNABLE了
消费者消费者1WAITING#
生产者生产者1RUNNABLE
生产者生产者1WAITING了#
消费者消费者1RUNNABLE了
消费者消费者1WAITING#
生产者生产者1RUNNABLE
生产者生产者1WAITING了#
消费者消费者1RUNNABLE了
消费者消费者1WAITING#
生产者生产者1RUNNABLE
生产者生产者1WAITING了#
消费者消费者1RUNNABLE了
消费者消费者1WAITING#
生产者生产者1RUNNABLE
生产者生产者1WAITING了#
消费者消费者1RUNNABLE了
消费者消费者1WAITING#
生产者生产者1RUNNABLE
生产者生产者1WAITING了#
消费者消费者1RUNNABLE了
消费者消费者1WAITING#
生产者生产者1RUNNABLE
生产者生产者1WAITING了#
消费者消费者1RUNNABLE了
消费者消费者1WAITING#
生产者生产者1RUNNABLE
生产者生产者1WAITING了#
消费者消费者1RUNNABLE了
消费者消费者1WAITING#
生产者生产者1RUNNABLE
生产者生产者1WAITING了#
消费者消费者1RUNNABLE了
消费者消费者1WAITING#
生产者生产者1RUNNABLE
生产者生产者1WAITING了#
消费者消费者1RUNNABLE了
消费者消费者1WAITING#
生产者生产者1RUNNABLE
生产者生产者1WAITING了#
消费者消费者1RUNNABLE了
消费者消费者1WAITING#
生产者生产者1RUNNABLE
生产者生产者1WAITING了#
消费者消费者1RUNNABLE了
消费者消费者1WAITING#
生产者生产者1RUNNABLE
生产者生产者1WAITING了#
消费者消费者1RUNNABLE了
生产者生产者1RUNNABLE
生产者生产者1WAITING了#
消费者消费者1RUNNABLE了
消费者消费者1WAITING#
消费者消费者2WAITING#
生产者生产者2RUNNABLE
生产者生产者2WAITING了#
消费者消费者1RUNNABLE了
消费者消费者1WAITING#
消费者消费者2WAITING#
生产者生产者1RUNNABLE
生产者生产者1WAITING了#
生产者生产者2WAITING了#
main  RUNNABLE
Monitor Ctrl-Break  RUNNABLE
生产者1  WAITING
消费者1  WAITING
生产者2  WAITING
消费者2  WAITING

假死状态:即最终生产者线程和消费者线程都处于wait状态。
* 解决假死的方法:
将上述类P和类C中的notify()改为notifyAll();

通过管道进行线程间通信:字节流
管道流是一种特殊的流,用于在不同线程之间直接传送数据。一个线程发送数据到输出管道,另一个线程从输入管道中读取数据。通过使用管道,实现不同线程间的通信,而无须借助于类似临时文件之类的问题。
通过管道进行线程间通信:字符流
join方法——同步方法

join方法的使用

在很多情况下,主线程创建并启动子线程,如果子线程中要进行大量耗时的操作,主线程往往会早于子线程而结束。如果在这种情况下,主线程想要等待子线程结束之后再结束,例如,主线程需要子线程中的一个数据,这种情况下我们就需要用到join方法。


方法join()的作用是使所属的线程对象x正常执行run()方法中的任务,而使当前线程z进行无周期的阻塞,等待线程x执行完毕之后再继续执行线程z后边的代码。

方法join与异常

在join过程中,如果当前线程对象被中断(调用interrupt()方法),则当前线程出现异常。而进行join()方法的线程无异常产生。

join(long)的使用

join(long)中的参数是设定等待的时间。

join(long)与sleep(long)方法的区别

方法join(long)的功能在内部是使用wait(long)方法来实现的,所以join(long)方法具有释放锁的特点。
方法sleep(long)不释放锁。  

ThreadLocal的使用

ThreadLocal解决的就是每一个线程绑定自己的值。可以将ThreadLocal类比喻为全局存放数据的盒子,盒子中可以存放每一个线程的私有数据。
也可以这么理解:类ThreadLocal解决的是变量在不同线程间的隔离性,也就是不同的线程拥有自己的值,不同线程中的值是可以放入ThreadLocal类中进行保存的。

类InheritableThreadLocal的使用

使用类InheritableThreadLocal可以在子线程中取得父线程继承下来的。但如果子线程在取得值的同时,主线程将类InheritableThreadLocal中的值进行更改,那么子线程取得的值还是旧值。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值