线程间的通信

1.等待通知机制

     wait()方法是object类的方法,将当前线程置入“预执行队列”中,并且在wait()所在的代码处停止执行,知道接收到通知或被中断为止。在调用wait()之前,线程必须获取对象级别的锁,即只能在同步方法或者同步代码块中调用wait()方法。执行完wait()方法后,释放对象锁,如果在wait()时没有持有适当的锁则会抛出异常!notify()方法也属于Object类,在notify()方法执行是,不会立即执行wait()所在代码,也不会立即释放对象锁,而是等notify()所在方法执行完。

     wait()方法执行后会释放锁,但是notify()执行后是不释放锁的,notify()方法每次只随机唤醒一个线程。当wait(时间)设置等待时间后,提前通知,则线程wait()中时间不会等待,反之则按wait()方法中设置的时间长度结束线程等待。

2.生产者消费者

     双方关系出现有一下几种情况:

     1)一生产-》一消费 

     2)一生产-》多消费 出现线程死循环

     3)多生产-》一消费 死循环

     4)多生产-》多消费 (当两边线程数相等时则程序正常结束, 否则也会出现死循环 个人测试)

3.通过管道进行线程间的通信:字节流、字符流

     jdk中提供了4个类使线程间进行通信

     1)PipedInputStream 和PieOutputStram

     2)  PipedReader 和PipedWrite

4.项目实例,交替执行数据

package javaBase.thread.wait_notify_test;
/**
 * 业务执行 每5个数据为单位交换一下处理方式
 * @author wodezuiaishinageren
 *
 */
public class DBTools {
volatile private boolean is_active=false;//此变量要共享
synchronized public void insertA(){
try{
while(is_active){
wait();
}
for (int i = 0; i <5; i++) {
System.out.println("*****");
}
is_active=true;
notifyAll();
}catch(InterruptedException exception){
exception.printStackTrace();
}
}
synchronized public void insertB(){
try{
while(!is_active){
wait();
}
for (int i = 0; i < 5; i++) {
System.out.println("*****");
}
is_active=false;
notifyAll();
}catch(InterruptedException exception){
exception.printStackTrace();
}
}

}

 

5.join 方法使用

    jdk源码 

    public final synchronized void join(long millis)
    throws InterruptedException {
        long base = System.currentTimeMillis();
        long now = 0;

        if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }

        if (millis == 0) {
            while (isAlive()) {
                wait(0);
            }
        } else {
            while (isAlive()) {
                long delay = millis - now;
                if (delay <= 0) {
                    break;
                }
                wait(delay);
                now = System.currentTimeMillis() - base;
            }
        }

    }

     join方法的作用是:在A线程中调用b线程,如果想A在B执行完之后在执行,则使用B.join()方法,join方法具有使线程排队运行的作用,但是,join是在内部使用wait()方法进行等待,而synchronized关键字是使用“对象监视器”原理作为同步。

     当join()与interrupt()方法相遇时则会出现异常。

     join(long)的功能内部使用的是wait(long)方法来实现的,所以join(long)方法具有释放锁的特点。当执行wait(long)时,源码中,当前线程的锁被释放,其它线程可以执行当前线程的同步方法,而Thread.sleep(long)则不会释放锁。

     

 

转载于:https://my.oschina.net/undermoonlightperson/blog/703291

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值