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

    1、线程间的通信主要靠三个方法
    (1)wait(),使当前线程放弃cpu、对象锁,重新排队等待对共享资源的访问
    (2)notify(),唤醒等待线程中优先级最高的线程,执行共享资源
    (3)notifyAll(),唤醒所有的等待线程
    (4)这三个方法是object里面的方法,而非thread方法,这些方法,只有在synchronized代码块或方法中才能使用
    否则会报,IlligalMonitorStateException,异常

    2、线程通信例子,要注意的事项在注释里面,实现两个线程轮流打印1到100的数据

    package com.thread.test;
    
    //实现两个线程轮流打印1到100的数据,synchronized所放位置有问题的例子
    class PrintNumber implements Runnable {
        int i = 0;
    
        @Override
        public void run() {
            synchronized (this) {// 有问题,如果这样,就会一个线程执行完while里面的代码后才出来
                notify();// 唤醒别的线程,因为当前线程已经拿到对象锁,所以可以唤醒其它线程
                while (i < 101) {
    
                    System.out.println("线程 " + Thread.currentThread().getName()
                            + " 打印出:" + i);
                    i++;
                }
                try {
                    wait();// 打印出一个数字后后等待
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    
    }
    
    // 下面锁的位置没有问题
    class PrintNumberNew implements Runnable {
        int i = 0;
    
        @Override
        public void run() {
    
            while (true) {
                synchronized (this) {// 有问题,如果这样,就会一个线程执行完while里面的代码后才出来
                    notify();// 唤醒别的线程,因为当前线程已经拿到对象锁,所以可以唤醒其它线程
                    if (i < 101) {
                        System.out.println("线程 " + Thread.currentThread().getName()
                                + " 打印出:" + i);
                        i++;
                    } else {
                        break;
                    }
                    try {
                        wait();// 打印出一个数字后后等待
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
    
            }
        }
    
    }
    
    /**
     * 线程间的通信主要靠三个方法 (1)wait(),使当前线程放弃cpu、对象锁,重新排队等待对共享资源的访问
     * (2)notify(),唤醒等待线程中优先级最高的线程,执行共享资源 (3)notifyAll(),唤醒所有的等待线程
     * (4)这三个方法是object里面的方法,而非thread方法,这些方法,只有在synchronized代码块或方法中才能使用
     * 否则会报,IlligalMonitorStateException,异常
     */
    
    public class 线程通信 {
        public static void main(String[] args) {
            PrintNumberNew pn = new PrintNumberNew();
    
            Thread t1 = new Thread(pn);
            Thread t2 = new Thread(pn);
    
            t1.setName("1");
            t2.setName("2");
            t1.start();
            t2.start();
        }
    }
  • 相关阅读:
    POJ 1061 青蛙的约会(扩展欧几里得)
    贝祖定理(裴蜀定理)
    C语言 gets()和scanf()函数的区别
    非递归方式遍历二叉树
    zip包的解压
    八大基础排序中(直接插入排序,希尔排序,冒泡排序, 快速排序,归并排序,简单选择排序)
    数字反序与数字的和
    合并两个有序数组,合并后数组仍有序
    使用递归方式和非递归方式求斐波那契数
    求100到999之内的水仙花数
  • 原文地址:https://www.cnblogs.com/fubaizhaizhuren/p/5066542.html
Copyright © 2011-2022 走看看