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)则不会释放锁。