精华内容
下载资源
问答
  • java 线程等待和唤醒(三种实现方式)
    2021-09-17 09:31:45

    1 synchronized
    等待 wait 唤醒 notify唤醒 还有一个 notifyAll 唤醒全部
    2 ReenTrantLock
    lock.newCondition
    await() 等待
    singal() 唤醒
    上面两个等待和唤醒有一个问题 是就是 要求顺序性和 必须加锁 比如 第一个线程 没有锁第二个线程也可以使用唤醒方法还不会抛出异常 但是 问题是 在运行编译的时候会报错 同时 在 等待和唤醒的顺序上也不能 搞混 如果 唤醒 先于等待 执行也会抛出异常
    3 LockSupport
    这里有 park() unpark() 线程阻塞 和 释放 这里没有这个问题 但是他们是成双成对出险 如果释放线程先于执行 那么后续在一个线程内部的park()的阻塞通通不生效 这个东西 在独立的线程内部只是第一个生效 如果 连续阻塞 只要有 有另一个线程释放了 所有阻塞都失效了 所以根据情况而定使用哪种方式
    这个 好处是 不会有异常 切不要求顺序 根据情况而定

     Thread thread = new Thread(() -> {
                try {
                    TimeUnit.SECONDS.sleep(2);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("1");
                  LockSupport.park();
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //这个不会生效 只要有释放他也会被置于 释放状态 
                LockSupport.park();
    
                System.out.println("2");
    
            }, "a");
            Thread threadw = new Thread(() -> {
    
            
    
                System.out.println("5");
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                LockSupport.park();
    
                System.out.println("6");
    
            }, "b");
            threadw.start();
            Thread thread2 = new Thread(() -> {
    
           
    
    
                System.out.println("3");
                LockSupport.unpark(thread);
    
                System.out.println("4");
    
    
            }, "c");
            thread2.start();
            thread.start();
    
    更多相关内容
  • 使用Object package study; public class Test { public static void main(String[] args) throws InterruptedException { ... System.out.println("进入线程t1"); synchronized (lock) { System.out.pr

    使用Object

    package study;
    
    public class Test {
    	public static void main(String[] args) throws InterruptedException {
    		Object lock = new Object();
    		Thread t1 = new Thread(() -> {
    			System.out.println("进入线程t1");
    			synchronized (lock) {
    				System.out.println("线程t1准备进入等待状态");
    				try {
    					lock.wait();
    				} catch (Exception e) {
    					e.printStackTrace();
    				}
    			}
    			System.out.println("线程t1撤出了");
    		});
    		t1.start();
    		Thread.sleep(1000);
    		System.out.println("主线程休眠完毕,准备唤醒t1线程");
    		synchronized (lock) {
    			lock.notify();
    		}
    	}
    }
    

    使用Condition

    package study;
    
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class Test1 {
    	static ReentrantLock lock = new ReentrantLock(); 
    	static Condition condition = lock.newCondition();
    	public static void main(String[] args) {
    		Thread t1 = new Thread(() -> {
    			lock.lock();
    			System.out.println("线程t1开始执行");
    			try {
    				try {
    					System.out.println("线程t1在condition上等待");
    					condition.await();
    				} catch (Exception e) {
    					e.printStackTrace();
    				}
    			} finally {
    				lock.unlock();
    			}
    			System.out.println("线程t1执行完毕");
    		});
    		t1.start();
    		System.out.println("主线程执行中");
    		try {
    			lock.lock();
    			System.out.println("主线程准备唤醒t1线程");
    			condition.signal();
    		} finally {
    			lock.unlock();
    		}
    	}
    }
    
    

    使用lockSupport

    package study;
    import java.util.concurrent.locks.LockSupport;
    
    
    public class Test2 {
    	public static void main(String[] args) throws InterruptedException {
    		Thread t1 = new Thread(() -> {
    			System.out.println("线程t1开始执行");
    			System.out.println("准备使用lockSupport让t1线程等待");
    			LockSupport.park();
    			System.out.println("线程t1结束等待,执行完毕");
    		});
    		t1.start();
    		System.out.println("主线程准备睡眠2秒");
    		Thread.sleep(2000);
    		System.out.println("主线程睡眠完毕,准备唤醒t1线程");
    		LockSupport.unpark(t1);
    	}
    }
    

    3种方式的区别

    在这里插入图片描述

    展开全文
  • 主要介绍了Java 线程状态和等待唤醒机制线程池的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • 线程等待和唤醒机制

    千次阅读 2022-03-15 14:31:53
    三种让线程等待和唤醒的方法: LockSupport类可以阻塞当前线程以及唤醒指定被阻塞的线程: 第一种方式:synchronized + wait + notify: 即使用Object中的wait方法让线程等待,使用Object中的notify方法唤醒线程: ...

    在这里插入图片描述

    三种让线程等待和唤醒的方法:
    在这里插入图片描述
    LockSupport类可以阻塞当前线程以及唤醒指定被阻塞的线程:

    第一种方式:synchronized + wait + notify:

    使用Object中的wait方法让线程等待,使用Object中的notify方法唤醒线程

    在这里插入图片描述

    代码演示:

    package com.fan.waitnotify;
    
    public class SyncDemo {
        //定义锁
        static Object obj = new Object();
        public static void main(String[] args) {
            new Thread(()->{
                synchronized (obj){//加锁
                    System.out.println(Thread.currentThread().getName()+
                            "\t ----come  in---");
                    try {
                        obj.wait();//同一个锁去等待
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()+
                            "被唤醒--");
                }
            },"A线程").start();
    
            //
            new Thread(()->{
                synchronized (obj){
                    obj.notify();//同一个锁去唤醒
                    System.out.println(Thread.currentThread().getName()+
                            "\t ---通知其他线程---");
                }
            },"B线程").start();
        }
    }
    
    

    存在的弊端:

    问题一:wait和notify 不能脱离synchronized代码块或者synchronized方法独自运行
    在这里插入图片描述

    在这里插入图片描述
    报异常,证明 wait + notify不能脱离synchronized 代码块或者方法

    问题二:wait + notify顺序不能颠倒,只能先等待后唤醒
    在这里插入图片描述

    打印结果:发现处于阻塞状态:
    在这里插入图片描述
    被阻塞的结果,证明wait + notify顺序不能颠倒,只能先等待后唤醒。等待中的线程才能被唤醒,否则无法被唤醒

    在这里插入图片描述

    第二种方式:Lock + await + signal :

    使用JUC包中的Condition的await方法让线程等待,使用signal方法唤醒线程

    在这里插入图片描述

    代码演示:

    package com.fan.waitnotify;
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class LockDemo {
        //创建可重入的非公平锁
        static Lock lock = new ReentrantLock();
        static Condition condition = lock.newCondition();
        public static void main(String[] args) {
            //如果这个方法我们只想运行一次,则直接写到线程内
            new Thread(()->{
                lock.lock();//加锁
                try {
                    System.out.println(Thread.currentThread().getName()+
                            "\t -----进来了----");
                    try {
                        condition.await();//等待
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    //
                    System.out.println(Thread.currentThread().getName()+
                            "\t -----被唤醒----");
                } finally {
                    lock.unlock();//解锁
                }
            },"A").start();
    
            new Thread(()->{
                lock.lock();
                try {
                    condition.signal();//唤醒
                    System.out.println(Thread.currentThread().getName()+
                            "\t -----通知其他线程----");
                } finally {
                    lock.unlock();
                }
            },"B").start();
        }
    }
    
    

    在这里插入图片描述

    存在的问题:

    问题一:lock和await和signal必须一起使用才行,await和signal不能脱离lock单独使用;
    在这里插入图片描述
    出现异常:证明lock和await和signal必须一起使用才行;
    在这里插入图片描述

    问题二:必须要先等待,后唤醒;调换顺序不能正常运行;
    在这里插入图片描述

    同样存在问题:必须要先等待,后唤醒;

    在这里插入图片描述

    总结:传统的synchronized 和Lock实现等待唤醒通知的约束

    在这里插入图片描述

    第三种方式:LockSupport + park +unpark :

    即LockSupport类的park方法可以 阻塞当前线程,使用unpark 方法唤醒指定被阻塞的线程

    注意:
    park相当于wait,unpark相当于notify

    LockSupport是什么:

    在这里插入图片描述

    在这里插入图片描述

    park方法:
    在这里插入图片描述

    unpark方法:
    在这里插入图片描述

    代码演示:

    package com.fan.waitnotify;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.locks.LockSupport;
    public class ParkDemo {
        public static void main(String[] args) {
            Thread A = new Thread(()->{
                //测试  先通知后阻塞:
                /*try { TimeUnit.SECONDS.sleep(3);}
                catch (InterruptedException e) {e.printStackTrace();}*/
                System.out.println(Thread.currentThread().
                        currentThread().getName()+"\t ----进来了----");
                LockSupport.park();//当前线程被阻塞
                System.out.println(Thread.currentThread().
                        currentThread().getName()+"\t ----被唤醒----");
            },"A");
            A.start();
            //让A线程先运行
            try { TimeUnit.SECONDS.sleep(1);}
            catch (InterruptedException e) {e.printStackTrace();}
            Thread B = new Thread(() -> {
                LockSupport.unpark(A);//唤醒 被阻塞的 线程实例
                System.out.println(Thread.currentThread().
                        currentThread().getName()+"\t ----通知了----");
            }, "B");
            B.start();
        }
    }
    
    

    在这里插入图片描述
    在这里插入图片描述

    测试 先通知后阻塞:发现可以正常运行;
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    重点:
    在这里插入图片描述

    LockSupport面试题:

    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述

    展开全文
  • Object中的wait()、notify()让线程等待和唤醒 Object.wait()、Object.notify()方法必须再synchronized修饰的代码块中才能正常使用,否则会报异常(语法不会显示有错误) 如下如果注释synchronized (obj)会报java.lang....

    Object中的wait()notify()让线程等待和唤醒

    Object.wait()Object.notify()方法必须再synchronized修饰的代码块中才能正常使用,否则会报异常(语法不会显示有错误)

    如下如果注释synchronized (obj)会报java.lang.IllegalMonitorStateException: current thread is not owner

    正常使用必须在synchronized中使用!
    public static void main(String[] args) {
        Object obj = new Object();
        new Thread(() -> {
           // synchronized (obj) {
                System.out.println(Thread.currentThread().getName() + "\t======== 进入");
                try {
                    obj.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "\t======== 被唤醒");
           // }
        }, "A").start();
    
        new Thread(() -> {
            //synchronized (obj) {
                obj.notify();
                System.out.println(Thread.currentThread().getName()+"\t============ 通知");
            //}
        }, "B").start();
    }
    

    Condition中的await()signal()让线程等待和唤醒

    Condition需要在ReentrantLock下使用,也就是需要上锁和释放锁,否则也会报java.lang.IllegalMonitorStateException

    public static void main(String[] args) {
        ReentrantLock lock = new ReentrantLock();
        Condition condition=lock.newCondition();
    
        new Thread(() -> {
    //            lock.lock();
                System.out.println(Thread.currentThread().getName() + "\t======== 进入");
                try {
                    condition.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
    //                    lock.unlock();
                }
                System.out.println(Thread.currentThread().getName() + "\t======== 被唤醒");
        }, "A").start();
    
        new Thread(() -> {
    //            lock.lock();
            try {
                condition.signal();
                System.out.println(Thread.currentThread().getName()+"\t============ 通知");
            } finally {
    //                lock.unlock();
            }
        }, "B").start();
    }
    

    LockSupport中的park()unpark()

    LockSupport调用unpark方法最多只发放一个许可证,调用park则需要消耗一个许可证。
    换而言之

    如下的逻辑虽然调用了两次unpark,但LockSupport只发放一个许可证

    LockSupport.unpark(t1)//需要传入参数线程t1
    LockSupport.unpark(t1)//需要传入参数线程t1
    LockSupport.park()
    LockSupport.park()// 线程会阻塞
    

    另外LockSupport.park()和LockSupport.unpark()不影响正常使用阻塞

    LockSupport.unpark(t1)//需要传入参数线程t1
    LockSupport.park()
    // 上面的顺序和下面的调用顺序,两者的作用相同
    LockSupport.park()
    LockSupport.unpark(t1)//需要传入参数线程t1
    

    总而概之,LockSupport是一个线程阻塞的工具类,里面的所有方法都是静态的

    相关文章:

    1、LockSupport源码的简化

    2、LockSupport中文文档

    展开全文
  • java线程等待和唤醒

    千次阅读 2018-12-26 22:34:53
    notify() :唤醒在此对象监视器上等待的单个线程。 notifyAll() : 唤醒在此对象监视器上等待的所有线程。 wait():让当前线程处于“等待(阻塞)状态”,“直到其他线程调用此对象的 notify() 方法或 notifyAll() ...
  • 我们都知道,Android的Handler机制,会在线程中开启消息循环,不断的从消息队列中取出消息,这个机制保证了主线程能够及时...这篇文章主要还是想聊聊,主线程等待和唤醒的时机的问题。 1.异步消息同步消息 当Message
  • 线程等待唤醒

    千次阅读 2018-08-15 17:42:12
    wait(), notify(), notifyAll()等方法介绍 在Object.java中,定义了wait(), notify()notifyAll()等接口...而notify()notifyAll()的作用,则是唤醒当前对象上的等待线程;notify()是唤醒单个线程,而notifyAll()...
  • 典型实例有生产者消费者,本文也通过实例来分析线程等待唤醒机制。  1、相关API介绍  public final void notify()  唤醒在此对象监视器上等待的单个线程,如果所有线程都在此对象上等待,则会任意选择唤醒...
  • Java线程等待唤醒机制(加深理解)

    万次阅读 多人点赞 2019-08-04 16:28:06
    这里就用到了线程等待唤醒机制,下面具体看一下。 等待唤醒机制示例 下面代码是一个简单的线程唤醒机制示例,主要就是在Activity启动的时候初始化并start线程,线程start后会进入等待状态,在onResume方法中执行...
  • 等待唤醒案例(线程之间的通信) 实现: 等待唤醒案例:线程之间的通信 创建一个顾客线程(消费者):告知老板要的包子的种类数量,调用wait方法,放弃cpu的执行,进入到WAITING状态(无限等待) 创建一个老板线程(生产...
  • pthread_cond_timedwait()函数pthread_cond_wait()函数,其实2个函数都差不多,我主要是要用pthread_cond_timedwait()函数。 pthread_cond_timedwait()函数有三个入口参数: (1)pthread_cond_t __cond:条件变量...
  • 本篇文章给大家分享了关于Java中线程等待唤醒的知识点内容,有需要的朋友们可以学习下。
  • 线程等待唤醒机制

    千次阅读 2017-05-09 11:03:26
    为了避免此类问题,我们会用到线程间的通信,而等待唤醒机制,就是线程间通信的一种形式。 等待唤醒机制用到的方法主要有: public final void wait() throws InterruptedException : 当前线程
  • C++大量线程等待唤醒

    千次阅读 2020-06-20 18:01:36
    线程等待和唤醒使用条件变量condition_variable锁mutex结合实现,其中条件变量提供了wait(), notify(), notifyAll()等方法。 wait()的作用是让当前线程进入等待状态,同时,wait()也会让当前线程释放它所持有的...
  • Java多线程5-线程等待唤醒

    千次阅读 2021-02-13 00:08:23
    1、wait(),notify(),notifyAll()等方法介绍在object.java中,定义了wait(),notify(),notifyAll...而notify()notifyAll()的作用,则是唤醒当前对象上的等待线程;notify()是唤醒单个线程,而notifyAll()是唤醒...
  • 在Object.java中,定义了wait(), notify()notifyAll()等接口。wait()的作用是让当前线程进入等待状态,同时,wait()也会让当前线程释放...下面通过本文给大家介绍Java中线程等待唤醒知识,感兴趣的朋友一起看看吧
  • //唤醒消费者的线程 mutex.unlock(); } } class Consumer : public QThread//消费者 { public: Consumer(); void run(); }; Consumer::Consumer() { } void Consumer::run() { forever { mutex.lock(); if...
  • 主要介绍了Java 实现多线程切换等待唤醒交替打印奇偶数 ,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
  • 一、wait()、notify()、notifyAll()等方法介绍在Object.java中,定义了wait(), notify()notifyAll()...而notify()notifyAll()的作用,则是唤醒当前对象上的等待线程;notify()是唤醒单个线程,而notifyAll()是唤...
  • Java写的消费者生产者模式,主要用到线程同步、线程等待和线程唤醒
  • 主要介绍了对线程等待/唤醒方法,文中使用了多个示例,大家参考使用吧
  • 请用“等待唤醒”机制编写一个程序 要求: 第一个线程:遍历1–1000所有的数字,在遍历过程中,如果发现这个数字能同时被2,3,5,7整除,立即wait()等待,让第二个线程进入。 第二个线程:运行后,将一个计数器 + 1,...
  • 主要介绍了Java等待唤醒机制线程通信原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • Java中wait(),notify()线程等待唤醒- Java多线程系列教程四在Object.java中,定义了wait(), notify()notifyAll()等接口。wait()的作用是让当前线程进入等待状态,同时,wait()也会让当前线程释放它所持有的锁。...
  • Java线程阻塞和唤醒的几种方式

    千次阅读 2020-12-17 10:04:09
    使用wait()方法来阻塞线程,使用notify()notifyAll()方法来唤醒线程。 调用wait()方法后,线程将被阻塞,wait()方法将会释放当前持有的监视器锁(monitor),直到有线程调用notify/notifyAll()方法后方能继续执行。 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 196,566
精华内容 78,626
关键字:

线程等待和唤醒