java join notify_Java多线程技术-wait/notify/join

wait/notify的作用

wait()方法的作用是使当前执行代码的线程进行等待,wait()是Object类的方法,用来将当前线程置入预执行队列中,并且在wait()所在的代码处停止执行,直到接到通知或被中断为止。wait()调用前,必须获得该对象的对象级锁,即只能在同步方法或者同步代码块中调用wait()方法,否则会抛出IllegalMonitorStateException。当wait()执行后,当前线程释放锁

notify()方法的作用是用来通知那些可能等待该对象的对象锁的其他线程,如果有多个线程等待,则随机挑选出一个wait状态的线程,对其发出通知,并使它等待获取该对象的对象锁。notify()调用前,必须获得该对象的对象级锁,即只能在同步方法或者同步代码块中调用notify()方法,否则会抛出IllegalMonitorStateException。当notify()方法执行后,不会马上释放该对象的锁,呈wait状态的线程也并不能马上获得该对象锁,要等到执行notify()的线程将程序执行完,也就是退出synchronized代码块后,当前线程才会释放锁。

notifyAll()方法和notify()作用基本是一样的,一个是唤醒全部的wait线程,一个是唤醒其中一个wait线程。

经典案例生产者和消费者

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

public classMyStack {private List list = new ArrayList<>();public synchronized voidpush() {try{while (list.size() == 1) {

System.out.println("push:"+Thread.currentThread().getName()+"呈wait状态");this.wait();

}

list.add("anyString=" +Math.random());this.notifyAll();

System.out.println("push=" +list.size());

}catch(InterruptedException e) {//TODO Auto-generated catch block

e.printStackTrace();

}

}public synchronizedString pop(){

String returnValue= "";try{while(list.size() == 0){

System.out.println("pop:"+Thread.currentThread().getName()+"呈wait状态");this.wait();

}

returnValue= list.get(0);

list.remove(0);this.notifyAll();

System.out.println("pop="+list.size());

}catch(InterruptedException e) {//TODO Auto-generated catch block

e.printStackTrace();

}returnreturnValue;

}

}public classProduct {privateMyStack myStack;publicProduct(MyStack myStack) {this.myStack =myStack;

}public voidpushService(){

myStack.push();

}

}public classCustomer {privateMyStack myStack;publicCustomer(MyStack myStack) {this.myStack =myStack;

}public voidpopService(){

myStack.pop();

}

}public class ThreadCustomer extendsThread {privateCustomer customer;publicThreadCustomer(Customer customer) {this.customer =customer;

}

@Overridepublic voidrun() {while(true){

customer.popService();

}

}

}public class ThreadProduct extendsThread {privateProduct product;publicThreadProduct(Product product) {this.product =product;

}

@Overridepublic voidrun() {while(true){

product.pushService();

}

}

}public classTest {public static void main(String[] args) throwsInterruptedException {

MyStack myStack= newMyStack();

Product p= newProduct(myStack);

Customer c= newCustomer(myStack);

ThreadProduct pThread= newThreadProduct(p);

ThreadCustomer cThread= newThreadCustomer(c);

pThread.start();

cThread.start();

}

}

View Code

join的作用

join()是Thread类的一个方法,它的作用是使所属的线程x对象正常的执行run方法中的任务,而使当前线程z进行无限期的阻塞,等待线程x销毁后再继续执行线程z后面的代码。

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

public class MyThread extendsThread{

@Overridepublic voidrun() {try{

System.out.println(System.currentTimeMillis());

Thread.sleep(3000);

}catch(InterruptedException e) {//TODO Auto-generated catch block

e.printStackTrace();

}

}

}public classTest {public static void main(String[] args) throwsInterruptedException {

MyThread myThread= newMyThread();

myThread.start();

myThread.join();

System.out.println("在myThread执行完后输出:" +System.currentTimeMillis());

}

}

View Code

测试结果:

1516170164683在myThread执行完后输出:1516170167686

join和synchronized的区别

从上面的例子可以看出,join方法具有线程排队运行的作用,有些类是同步的运行效果。join和synchronized的区别是:join在内部使用wait()方法进行等待,而synchronized是使用“对象监视器”原理做为同步

join(long)和sleep(long)的区别

由于join的内部是使用wait来实现的,所以它具有释放锁的特点,而sleep没有这一特点。

源码如下:

public final synchronized void join(longmillis)

throwsInterruptedException {

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;

}

}

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值