精华内容
下载资源
问答
  • 多线程 等待唤醒机制

    2018-09-05 17:28:00
    一.线程间通信  概念: 线程在处理同一个资源,但是处理的动作(线程的任务)却不相同  原因: 线程并发执行时,在默认...等待唤醒机制  wait / notify就是线程间的一种协作机制,可以完成线程间的通信  ...

    一.线程间通信

      概念: 多个线程在处理同一个资源,但是处理的动作(线程的任务)却不相同

      原因: 多个线程并发执行时,在默认情况下,Cpu是随机切换线程的,如果我们需要多个线程共同完成一件任务,并且我们希望他们有规律的执行,那么多线程之间需要一些协调通信,帮我们多线程共同操作一份数据

    二.等待唤醒机制

      wait / notify就是线程间的一种协作机制,可以完成线程间的通信

      相关API:

        void wait(): 让线程等待,直到有其他线程调用notify或者notifyAll唤醒这个线程

        void wait(long timeout): 让线程等待,直到有其他线程调用notify或者notifyAll,或者等待时间到了线程自己会醒

        void notify(): 唤醒一个线程

        void notifyAll:  唤醒所有线程

      注意:  

        1. 上面的方法虽然是Object中的方法,但是不能直接通过对象调用,要放在同步代码块中,使用锁对象调用

        2. notify方法唤醒的是当前同步代码块中等待的线程

        3. 线程调用wait 方法后,会释放掉所对象

      wiia方法和sleep方法的区别:

        wait会释放锁

        sleep不会释放锁

      

    转载于:https://www.cnblogs.com/xiangshaui/p/9593401.html

    展开全文
  • 多线程等待唤醒机制

    2018-04-22 23:19:28
    进入while循环,经同步锁进入同步代码块中,if(r.flag)判定,线程a未进入等待,直接进行if(k==0)判定,分别赋值Mike和man,此时和输出我们设定的观测语句“wozai mikezheli”,运行完接下来的语句且唤醒线程b,...

    示例代码取自传智播客毕向东老师25天Java基础教程,添加了一些观测打印代码,便于理解分析。对于进程分析理解纯粹个人理解,刚学Java没多久,难免有错,仅供参考,如果大神们发现错误,希望能帮忙指出,也帮我走出错误的理解。

    先贴代码

    class Res{
    	String name;
    	String sex;
    	boolean flag=false;
    }
    class Input implements Runnable{
    	private Res r;
    	public Input(Res r) {
    		this.r=r;
    	}
    	public void run() {
    		int k=0;
    		int a=0;//设定线程中有限次循环参数,便于观测运行数据
    		while (a<5) {	//设定循环5次
    			synchronized(r) {//设定同一锁
    				if(r.flag)
    					try {
    						System.out.println("设置参数休眠");//用于观测本线程是否进入休眠
    						r.wait();
    						} catch (Exception e)
    				{}
    			if(k==0) {				
    				r.name="Mike";
    				r.sex="man";
    				System.out.println("wozai mikezheli");//用于观测本是否进行此处成员变量赋值
    			}else {	
    				r.name="丽丽";
    				r.sex="女女女女女女";
    				System.out.println("我在 丽丽这里");//用于观测本是否进行此处成员变量赋值
    			}
    			a++;
    			k=(k+1)%2;
    			r.flag=true;
    			r.notify();
    			}
    			
    		}		
    	}	
    }
    class Output implements Runnable{
    	private Res r;
    	Output(Res r){
    		this.r=r;
    	}
    	public void run() {
    		int b=0;
    		while (b<5) {	
    			synchronized(r) {
    				if(!r.flag)
    					try {
    						System.out.println("打印参数休眠*****");//用于观测本线程是否进入休眠
    						r.wait();
    						} catch (Exception e)
    				{}
    			System.out.println(Thread.currentThread().getName()+r.name+"------"+r.sex);
    			b++;
    			r.flag=false;
    			r.notify();
    			}
    			
    		}		
    	}	
    }
    
    public class InOutput {
    	public static void main(String[] args) {
    		Res r=new Res();
    		Input in=new Input(r);
    		Output out=new Output(r);
    		Thread t1=new Thread(in);
    		Thread t2=new Thread(out);
    		t1.start();	
    		t2.start();			
    	}
    }

    运行结果:1、

    wozai mikezheli
    打印输出线程b Mike------man
    打印参数休眠*****
    我在 丽丽这里
    打印输出线程b 丽丽------女女女女女女
    打印参数休眠*****
    wozai mikezheli
    打印输出线程b Mike------man
    打印参数休眠*****
    我在 丽丽这里
    打印输出线程b 丽丽------女女女女女女
    打印参数休眠*****
    wozai mikezheli
    打印输出线程b Mike------man
    
    这是出现最多的一种结果。首先赋值线程a启动,进入while循环,经同步锁进入同步代码块中,if(r.flag)判定,线程a未进入等待,直接进行if(k==0)判定,分别赋值Mike和man,此时和输出我们设定的观测语句“wozai mikezheli”,运行完接下来的语句且唤醒线程b,结束同步代码块。注意:此时线程a与b都是就绪状态,都可执行!!由结果可知,线程a再次抢夺到运行资质(NB啊),经同步锁进入同步代码块中,if(r.flag)判定,线程a进入等待(白抢了),同时放弃已占有的同步锁资源。线程b经同步锁进入同步代码块,经if(!r.flag)判断,线程b未进行等待。执行代码输出语句“打印输出线程b Mike------man”,运行完接下来的语句且唤醒线程a,结束同步代码块。此时a与b又都进入到就绪状态,抢夺执行权。由结果知b抢到了,但由于判断条件的参数改变,只能去等待,a执行赋值后唤醒b,结束同步代码块。再次竞争。。。。不管哪次竞争结果如何,如果刚执行完的线程抢到,由于参数设置的改变,都只能进入等待,对外表现为两线程交替执行。如果俩线程都处于就绪状态,竞争应该一直存在,未必只发生在俩线程都在同步代码块外面的时候,只不过,某一线程即使争到了也进不去同步锁或只能进入等待。以上分析大概率是错的,对于编程知道的太少了,只是现阶段的个人理解。
    还有一种比较特别的结果(运行很多次会出现):
    打印参数线程b休眠*****
    wozai mikezheli
    打印输出线程b Mike------man
    打印参数线程b休眠*****
    我在 丽丽这里
    设置参数线程a休眠
    打印输出线程b 丽丽------女女女女女女
    打印参数线程b休眠*****
    wozai mikezheli
    设置参数线程a休眠
    打印输出线程b Mike------man
    打印参数线程b休眠*****
    我在 丽丽这里
    设置参数线程a休眠
    打印输出线程b 丽丽------女女女女女女
    打印参数线程b休眠*****
    wozai mikezheli
    打印输出线程b Mike------man

    虽然线程a在主线程中先启动,线程b后启动,但是在第一次的竞争中还是输了,唉。。

    学习Java三十多天,对于编程知识所知太少,分享只为交流个人理解,仅供参考,难免有错。希望有大神如果发现我理解中的错误,一定指出来!

    对了,上面应该是等待,不是休眠!!


    展开全文
  • 1.多线程等待唤醒机制 1.1等待唤醒机制概述: 等待唤醒机制是实现两个或多个线程在执行任务过程中相互配合相互协作的一种技术。 典型应用场景:生产者与消费者案例。      线程等待与唤醒: 线程等待与...

    1.多线程等待唤醒机制

    1.1等待唤醒机制概述

    • 等待唤醒机制是实现两个或多个线程在执行任务过程中相互配合相互协作的一种技术。
    • 典型应用场景:生产者与消费者案例

     

     

    •  线程等待与唤醒:
    1. 线程等待与唤醒又称为线程间通信。
    2. 等待唤醒机制是实现两个或多个线程在执行任务过程中相互配合相互协作的一种技术。
    • 线程等待与唤醒相关的方法:
    1. void wait();等待,让线程释放CPU的使用权进入无限等待状态。
    2. void notify();唤醒,随机唤醒一个正在等待状态的线程,让其进入可运行状态。
    3. void notifyAll();唤醒所有,唤醒所有正在等待状态的线程,让其进入可运行状态。
    • 以上三个方法必须由锁对象调用且必须在同步代码块或同步方法中调用
    • java.lang.IllegalMonitorStateException:非法监视器状态异常=>

    2.1.等待唤醒机制案例: 

     

     

    public class Resource {
        public String name;
        public String gender;
    
    }
    
    
    
    public class ProductThread implements Runnable {
        private Resource r;
    
        public ProductThread(Resource r) {
            this.r = r;
        }
    
        int index=0;
        @Override
        public void run() {
            while (true){
                //使用同步代码块实现线程安全
                synchronized (r){
                    if(index % 2 == 0){
                        r.name="陈奕迅";
                        r.gender="男";
                    }else {
    
                        r.name="lily";
                        r.gender="女";
                    }
                    try {
                        //唤醒消费线程消费数据
                        r.notify();
                        //让当前线程进入等待状态
                        r.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                //索引++
                index++;
            }
        }
    }
    
    
    
    
    
    public class ConsumerThread implements Runnable {
       private Resource r;
    
        public ConsumerThread(Resource r) {
            this.r = r;
        }
    
        @Override
        public void run() {
            while(true){
                //使用同步代码块实现线程安全
                synchronized (r){
                    //判断生成线程是否已经产生了数据
                    if(r.name == null){
                        //让当前线程进入等待状态
                        try {
                            r.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println(r.name+"="+r.gender);
                    try {
                        //唤醒生成线程
                        r.notify();
                        //让当前线程进入等待状态
                        r.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    
    
    
    
    
    public class ThreadDemo {
        public static void main(String[] args) {
            //创建资源对象
            Resource r=new Resource();
    
            //创建生产和消费线程
            Thread pt = new Thread(new ProductThread(r));
            Thread ct = new Thread(new ConsumerThread(r));
    
            //开启线程
            pt.start();
            ct.start();
        }
    }
    

     


    2.2. sleep和wait的区别:(面试题)

    • sleep方法调用需要指定时间,wait方法调用可以指定时间也可以不指定。
    • sleep方法不会释放锁对象,wait方法会释放锁对象。
    • sleep方法可以在任意类任意方法中调用,wait方法必须通过锁对象在同步代码块或同步方法中调用。
    • sleep方法不需要被唤醒,wait方法如果没有指定时间则需要被唤醒。

    3.1 Lambda表达式概述

    • Lambda表达式概述:JDK1.8新特性,用来简化匿名内部类。
    • Lambda表达式思想:只专注做什么,而不是怎么做。
    • Lambda表达式的标准格式:
    • (参数列表)- >{方法体}
    • 小括号就是方法的参数列表
    • ->新语法,代表动作执向
    • 大括号就是方法体
    • Lambda表达式的使用前提:必须有接口且接口中有且只有一个抽象方法

    案例1:开启一个线程执行一个任务,任务是在控制台中输出: 我用java书写人生

    public class LambdaDemo {
        public static void main(String[] args) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("我用java书写人生");
                }
            }).start();
    
            //使用Lambda表达式简化匿名内部类
           new Thread(()->{
               System.out.println("我用java书写人生");
           }).start();
        }
    }
    

    案例2: Lambda之Comparator接口使用 

    1. 定义一个学生类,成员变量有:姓名,年龄,成绩。

    2. 创建多个学生对象添加到集合中,对集合的学生对象进行排序(升序和降序) 

    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.Comparator;
    
    /*
        1. 定义一个学生类,成员变量有:姓名,年龄,成绩。
        2. 创建多个学生对象添加到集合中,对集合的学生对象进行排序(升序和降序)
     */
    public class LambdaDemo01 {
        public static void main(String[] args) {
            //创建集合对象
            ArrayList<Student> list=new ArrayList<>();
            list.add(new Student("马化腾",18,100));
            list.add(new Student("马云",21,99));
            list.add(new Student("雷军",24,96));
            list.add(new Student("李彦宏",35,87));
    
            /*//对集合学生排序,按成绩升序排序
            Collections.sort(list, new Comparator<Student>() {
                @Override
                public int compare(Student o1, Student o2) {
                    return o1.getScore()-o2.getScore();
                }
            });*/
            //使用Lambda表达式的标准格式简化
            Collections.sort(list,(Student o1, Student o2)->{
                return o1.getScore()-o2.getScore();
            });
    
           for(Student student:list){
               System.out.println(student);
           }
    
        }
    }
    

     案例3:使用Lambda标准格式(无参无返回)

    给定一个厨子 Cook 接口,内含唯一的抽象方法 makeFood ,且无参数、无返回值。如下:
    interface Cook{

         void makeFood();

         default void xx(){}

    }

    在下面的代码中,请使用Lambda的标准格式调用 invokeCook 方法,打印输出“吃饭啦!”字样:
     

    public class LambdaDemo02 {
        public static void main(String[] args) {
            invokeCook(new Cook() {
                @Override
                public void makeFood() {
                    System.out.println("吃饭啦!");
                }
            });
    
            //使用Lambda的标准格式调用 invokeCook 方法,打印输出“吃饭啦!”
            invokeCook(()->{
                System.out.println("吃饭啦!");
            });
        }
        private static void invokeCook(Cook cook){
            cook.makeFood();
        }
    }
    
    interface Cook{
        void makeFood();
    }
    
    

    案例4: 使用Lambda标准格式(有参有返回)

    给定一个计算器 Calculator 接口,内含抽象方法 calc 可以将两个int数字相加得到和值:
    interface Calculator{

        int calc(int a,int b);

    }

    在下面的代码中,请使用Lambda的标准格式调用 invokeCalc 方法,完成120和130的相加计算:
     

    interface Calculator{
        int calc(int a,int b);
    }
    public class LambdaDemo {
        public static void main(String[] args) {
            //使用匿名内部类调用
            invokeCalc(120, 130, new Calculator() {
                @Override
                public int calc(int a, int b) {
                    return a+b;
                }
            });
    
            invokeCalc(120,130,(int a,int b)->{
                return a+b;
            });
            //请使用Lambda的标准格式调用 invokeCalc 方法,完成120和130的相加计算:
        }
        private static void invokeCalc(int a,int b,Calculator calculator){
            int result = calculator.calc(a,b);
            System.out.println("结果是:"+result);
        }
    }
    

    3.2 Lambda的省略格式

    • 在Lambda标准格式的基础上,使用省略写法的规则是:
    • (参数列表)-> {方法体}
    • 参数的数据类型可以省略。
    • 如果参数列表中只有一个参数时,小括号可以省略。
    • 如果方法体中只有一条语句时,大括号也可以省略,如果省略了大括号则return语句和分号必须省略。

     

    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.Comparator;
    
    /*
        1. 定义一个学生类,成员变量有:姓名,年龄,成绩。
        2. 创建多个学生对象添加到集合中,对集合的学生对象进行排序(升序和降序)
     */
    public class LambdaDemo01 {
        public static void main(String[] args) {
            //创建集合对象
            ArrayList<Student> list=new ArrayList<>();
            list.add(new Student("马化腾",18,100));
            list.add(new Student("马云",21,99));
            list.add(new Student("雷军",24,96));
            list.add(new Student("李彦宏",35,87));
    
            /*//使用Lambda表达式的标准格式简化
            Collections.sort(list,(Student o1, Student o2)->{
                return o1.getScore()-o2.getScore();
            });*/
    
            //使用Lambda表达式的简化格式
            Collections.sort(list,( o1, o2)->  o1.getScore()-o2.getScore());
    
           for(Student student:list){
               System.out.println(student);
           }
    
        }
    }
    

    3.3  使用lambda表达式对集合进行遍历

    import java.util.*;
    import java.util.function.Consumer;
    
    public class LambdaDemo01 {
        public static void main(String[] args) {
            //创建集合对象
            ArrayList<Student> list=new ArrayList<>();
            list.add(new Student("马化腾",18,100));
            list.add(new Student("马云",21,99));
            list.add(new Student("雷军",24,96));
            list.add(new Student("李彦宏",35,87));
    
            //使用匿名内部类遍历集合
            list.forEach(new Consumer<Student>() {
                @Override
                public void accept(Student student) {
                    System.out.println(student);
                }
            });
            System.out.println("------------------");
            //使用Lambda的标准格式遍历集合
            //public void forEach(Consumer<? super E> action)
             list.forEach((Student student)->{
                 System.out.println(student);
             });
    
            System.out.println("--------------------");
    
            //使用Lambda的简化格式遍历集合
            //void accept(T t);
            list.forEach(student -> System.out.println(student));
    
            System.out.println("-----------遍历set集合----------");
            Set<Integer> set=new HashSet<>();
    
            Collections.addAll(set,34,35,45,56,576,7,34);
            set.forEach(num -> System.out.println(num));
    
            System.out.println("-----------遍历map集合------------");
            //BiConsumer<? super K, ? super V> action
            // void accept(T t, U u);
            Map<String,String> map=new HashMap<>();
            map.put("name","jack");
            map.put("gender","男");
            map.forEach((key,value)-> System.out.println(key+"="+value));
        }
    }
    

    4.单例模式:

    • 单例实现方式(面试)

    单例模式概述:

    • 类在程序运行过程中有且只有一个对象。
    • 类必须私有构造方法。
    • 类必须要提供一个静态方法返回该类的单例对象。

    单例实现方式:

    • 懒汉式模式:在第一次访问该类的单例对象时,如果还没有创建出来,则创建,如果已经创建了 则直接返回。(线程不安全的)
    • 饿汉式模式:类加载的同时就创建该类的单例对象。(线程安全的)
    /*
        饿汉式模式:类加载的同时就创建该类的单例对象
     */
    public class Singleton {
        private static Singleton s=new Singleton();
        //私有构造方法
        private Singleton(){}
    
        //类必须提供一个静态方法返回该类的单例对象
        public static Singleton getInstance(){
            return s;
        }
    }
    
    
    public class SingleDemo {
        public static void main(String[] args) {
            System.out.println(Singleton.getInstance());
            System.out.println(Singleton.getInstance());
            System.out.println(Singleton.getInstance());
        }
    }
    /*
        day07Test04.Singleton@75412c2f
        day07Test04.Singleton@75412c2f
        day07Test04.Singleton@75412c2f
     */
    

     

    /*
        懒汉式模式:在第一次访问该类的单例对象时,如果还没有创建出来,则创建,如果已经创建了 则直接返回。
     */
    public class Singleton {
        private static Singleton s=null;
        //私有构造方法
        private Singleton(){}
    
        //类必须提供一个静态方法返回该类的单例对象
        public static Singleton getInstance(){
            //判断s是否已经创建了
            if(s == null){
                s = new Singleton();
            }
            return s;
        }
    }
    

    静态同步方法使用线程安全:不推荐使用,效率低

    使用同步代码块使用线程安全

    /*
        懒汉式模式:在第一次访问该类的单例对象时,如果还没有创建出来,则创建,如果已经创建了 则直接返回。
     */
    public class Singleton {
        private static Singleton s=null;
        //私有构造方法
        private Singleton(){}
    
        //类必须提供一个静态方法返回该类的单例对象
        public static Singleton getInstance(){
            if(s == null){
                synchronized (Singleton.class){
                    //判断s是否已经创建了
                    if(s == null){
                        s = new Singleton();
                    }
                }
            }
            return s;
        }
    }
    

     

    展开全文
  • JAVA多线程等待唤醒机制的小练习 场景概述: 包子铺(生产者)制作两种皮和馅的包子,每5秒制作一个包子,随机皮馅,在包子铺制作包子的线程中,顾客(消费者)无限等待(wait),直到包子制作完成后唤醒(notify)...

    JAVA多线程等待唤醒机制的小练习

    场景概述:
    包子铺(生产者)制作两种皮和馅的包子,每5秒制作一个包子,随机皮馅,在包子铺制作包子的线程中,顾客(消费者)无限等待(wait),直到包子制作完成后唤醒(notify)顾客进行吃包子进程。
    JAVA知识:
    主要练习JAVA多线程的等待唤醒机制。
    代码如下:

    第一部分是包子类的创建,这个类对象是两个线程共享的数据,所以需要做线程安全方便调用。

    public class baozi {
    
    	String pi;
    	String xian;
    	boolean flag=false;
    	
    }
    

    第二部分是包子铺类的创建,也就是制作包子的进程

    public class baozipu extends Thread {
    
    	
    	private baozi bz;
    	
    	int count=1;
    	
    	   public baozipu(baozi bz) {
    		super();
    		this.bz = bz;
    	}
    
    
    
    	@Override
    	public void run() {
    		// TODO Auto-generated method stub
    		
    		while(true){
    			synchronized (bz) {
    				
    				if(bz.flag==true){
    					try {
    						bz.wait();
    					} catch (InterruptedException e) {
    						// TODO Auto-generated catch block
    						e.printStackTrace();
    					}
    				}
    				
    				if(count%2==0){
    					bz.pi="薄皮";
    					bz.xian="猪肉韭菜";
    							
    				}else{
    					bz.pi="冰皮";
    					bz.xian="豆沙";
    				}
    				System.out.println("包子铺正在制作:"+bz.pi+bz.xian+"包子!");
    				try {
    					Thread.sleep(5000);
    				} catch (InterruptedException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    				System.out.println(bz.pi+bz.xian+"包子已经制作完成!");
    				bz.flag=true;
    				count++;
    				bz.notify();
    				System.out.println("#####################################################");
    				
    				
    			}
    		}
    		
    		
    	}
    	  
    	
    	
    	
    }
    

    第三部分是吃货顾客的类,也就是吃包子的进程。

    public class chihuo extends Thread{
    
    private baozi bz;
    	
    	int count=1;
    	
    	   public chihuo(baozi bz) {
    		super();
    		this.bz = bz;
    	}
    	
    	   public void run() {
    			// TODO Auto-generated method stub
    			
    			while(true){
    				synchronized (bz) {
    					
    					if(bz.flag==false){
    						try {
    							bz.wait();
    						} catch (InterruptedException e) {
    							// TODO Auto-generated catch block
    							e.printStackTrace();
    						}
    					}
    					
    					
    					System.out.println("吃货正在吃"+bz.pi+bz.xian+"包子!");
    					
    					
    					bz.flag=false;
    					
    					bz.notify();
    					System.out.println("#####################################################");
    					
    					
    				}
    			}
    			
    	   
    	   
    	   }
    	   }
    
    

    第四部分是demo测试效果主线程类:

    public class demo {
    
    	public static void main(String[] args) {
    		
    		 baozi bz = new baozi();
    		 new baozipu(bz).start();
    		 new chihuo(bz).start();
    		
    	}
    	
    }
    
    

    运行效果图如下:
    运行结果图

    展开全文
  • 通过等待唤醒机制可以使各个线程能有效的利用资源。   等待唤醒机制所涉及到的方法: wait():等待,将正在执行的线程释放其执行资格和执行权,并存储到线程池中。 notify():唤醒,唤醒线程池中被wait()...
  • java复习第6天---多线程----6.4--多线程等待唤醒机制 目录 文章目录1、线程状态2、线程间通信2、线程等待唤醒机制2.1、概述2.2、使用方法2.3、案例***后记*** : 内容 1、线程状态   线程具有生命周期,从...
  • 多线程等待唤醒机制简单入门  听完毕老师讲解的等待唤醒机制的原理。自己进行了简单的整理。   线程之间的关系是平等的,彼此之间并不存在任何依赖,它们各自竞争CPU资源,互不相让,并且还无条件地阻止其他线程对...
  • /** * 作者:kuma * 版本:v1.0 * */ public class study_12_1 { public static void main... //其实就是线程在操作同一个资源,但是操作的动作不同 res r=new res(); /*input in=new input(r); output out
  • ## java多线程等待唤醒机制的运用(wait(),notifyAll()) 解决问题:线程A,线程B,线程C按先后顺序:线程A—>线程B---->线程C 每个线程输出3个数, 比如:线程A (1 2 3)—>线程B(4 5 6)—>线程C(7 8 9)...
  • * 同时有2个线程,对资源中的变量操作 * 1个对name,age赋值 * 2个对name,age做变量的输出打印 */ public class Resource { public String name; public String sex; public boolean flag = false; } ...
  • 中关村黑马程序员训练营 ——————- 多线程间通讯及多线程等待唤醒机制.——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-多线程间通讯: 其实就是多个线程在操作同一个资源, 但是操作的动作...
  • /** * @param args * 等待唤醒机制 */public static void main(String[] args) {final Printer p = new Printer();new Thread() {public void run() {while(true) {try {p.print1();...
  • 上篇楼主说明了多线程中死锁产生的原因并抛出问题——死锁的解放方案,那么在本篇文章,楼主将引用一个KFC生产汉堡,顾客购买汉堡的过程来说明死锁解决方案及多线程等待唤醒机制。 简单地用一幅图来说明KFC生产...
  • 使用Java标准的等待唤醒通知机制等待唤醒通知方法模板 synchronized(lock){ while(条件不满足) lock.wait(); 执行操作 改变条件 lock.notifyAll(); } class FooBar { private int n; private boolea.....
  • 判断当前桌子上是否有汉堡,如果有汉堡,则生产者等待消费者吃掉;如果没有汉堡,消费者等待生产者制作汉堡 桌子类 package com.llb.provider_consumer.my; public class Desk { //汉堡个数 public static int ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,264
精华内容 505
关键字:

多线程等待唤醒机制