zoukankan      html  css  js  c++  java
  • 多线程通信

    什么是多线程的通信?

            多线程对同一共享资源的不同操作。

    wait()

          wait方法将当前的线程挂起,并释放出锁资源。wait方法属于Object类中。

    此方法应始终在循环中使用:

    synchronized (obj) {
    while (<condition does not hold>)
    obj.wait();
    ... // Perform action appropriate to condition
         }
     

    此方法只应由作为此对象监视器的所有者的线程来调用。

    package com.cn.test.thread;
    
    public class TestWait extends Thread{
    
        Object obj = new Object();
        
        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                   System.out.println("running start");
                    try {
                        obj.wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    System.out.println("running over");
                }
            }
        public static void main(String[] args) {
    
            TestWait testWait = new TestWait();
            testWait.start();
        }
    
    }

    此方法必须同sychnorized同时使用,不使用sychnorized直接调用此方法发生异常:

    running start
    Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
        at java.lang.Object.wait(Native Method)
        at java.lang.Object.wait(Object.java:502)
        at com.cn.test.thread.TestWait.run(TestWait.java:12)

    package com.cn.test.thread;
    
    public class TestWait extends Thread{
    
        Object obj = new Object();
        
        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                System.out.println("running start");
                synchronized (obj) {
                    try {
                        obj.wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    System.out.println("running over");
                }
            }
        }
        public static void main(String[] args) {
    
            TestWait testWait = new TestWait();
            testWait.start();
        }
    
    }

    运行结果:线程一直处于阻塞的状态

    running start

    obj.wait(long time); 

    该方法挂去time长的时间,时间已过,线程又处于竞争cpu的资源中、

    此方法导致当前线程(称之为 T)将其自身放置在对象的等待集中,然后放弃此对象上的所有同步要求。出于线程调度目的,在发生以下四种情况之一前,线程 T 被禁用,且处于休眠状态:

      • 其他某个线程调用此对象的 notify 方法,并且线程 T 碰巧被任选为被唤醒的线程。
      • 其他某个线程调用此对象的 notifyAll 方法。
      • 其他某个线程中断线程 T
      • 大约已经到达指定的实际时间。但是,如果 timeout 为零,则不考虑实际时间,在获得通知前该线程将一直等待。

    notify()唤醒在此对象监视器上等待的单个线程。如果所有线程都在此对象上等待,则会选择唤醒其中一个线程。选择是任意性的,并在对实现做出决定时发生。线程通过调用其中一个 wait 方法,在对象的监视器上等待。notifyAll()唤醒当前等待的所有的线程。

    notifyAll()唤醒在此对象监视器上等待的所有线程。线程通过调用其中一个 wait 方法,在对象的监视器上等待。

    例子: 生产者消费者,生产者写入数据,消费者进行消费数据

    package com.cn.test.thread;
    
    public class Resource {
         public String name;
         public String color;
         public boolean sychFlag = true; //同步标识
    }
    package com.cn.test.thread;
    
    public class Customer extends Thread{
    
        private Resource res;
        Customer(Resource res) {
            this.res = res;
        }
        
        @Override
        public void run() {
            while (true) {
                synchronized (res) {
                    if (!res.sychFlag) {
                        // 消费者进行消费
                        System.out.println("name=" + res.name + "color =" + res.color);
                        // 消费者消费完毕
                        res.sychFlag = true;
                        // 阻塞当前的线程
                        res.notifyAll();
    
                    } else {
                        try {
                            res.wait();
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }
    package com.cn.test.thread;
    
    public class Producer extends Thread{
    
        private Resource res;
        Producer(Resource res) {
            this.res = res;
        }
        @Override
        public void run() {
            /**
             * 同步标识为true生产者开始进行生产
             * 消费者进行等待
             */
            int count = 0;
            while (true) {
                synchronized (res) {
                    if (res.sychFlag) {
                        // 生产者进行生产
                        if (count % 2 == 0) {
                            res.name = "张三";
                            res.color = "blue";
                        } else {
                            res.name = "尤其";
                            res.color = "red";
                        }
                        count++;
                        res.sychFlag = false;
                        // 写完之后唤醒当前的线程
                        res.notifyAll();
                    } else {
                        // 阻塞当前线程,并且释放锁的资源
                        try {
                            res.wait();
                            Thread.sleep(100);
                            System.out.println("我被挂起了");
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
        
    }
    package com.cn.test.thread;
    
    public class TestMain {
    
        public static void main(String[] args) {
               Resource res = new Resource();
            Producer p = new Producer(res);
            Producer p2 = new Producer(res);
            Customer c = new Customer(res);
            Customer c1 = new Customer(res);
            c.start();
        //    c1.start();
            p.start();
        //    p2.start();
        }
    
    }
                    
  • 相关阅读:
    webpack2使用ch4-向根目录index.html文件传参并使用参数 使用线上资源 压缩html
    webpack2使用ch3-自动化生成.html和内部引入的js自动更改
    webpack2使用ch2-entry和output简要说明
    webpack2使用ch1-目录说明
    less使用ch1--简单使用
    less使用ch1--认识语法
    vue2购物车ch4-(筛选v-for 点击的那个设置样式 设为默认地址其他 联动 非循环的列表选中和非选中 删除当前选中的列表)
    gulp使用2-gulp-less及watch和错误提示
    gulp使用1-入门指南
    vue2购物车ch3-(过滤器使用 单件商品金额计算 全选全不选 总金额计算 删除商品功能)
  • 原文地址:https://www.cnblogs.com/startSeven/p/10236547.html
Copyright © 2011-2022 走看看