zoukankan      html  css  js  c++  java
  • 线程同步synchronized,wait,notifyAll 测试示例

    https://www.cnblogs.com/LipeiNet/p/6475851.html

    一  synchronized

    synchronized中文解释是同步,那么什么是同步呢,解释就是程序中用于控制不同线程间操作发生相对顺序的机制,通俗来讲就是2点,第一要有多线程,第二当多个线程同时竞争某个资源的时候会有先后顺序。在java中有三种写synchronized的方式

    • 第一种:
      • 写在普通方法的前面,这种表示对实例对象加锁。
    • 第二种:
      • 写在静态方法前面,这种表示对类对象加锁
    • 第三种:
      • 写在代码块中,锁是Synchonized括号里配置的对象(可能是实例对象,也可能是类对象)

    总体说来就2种,一种就是锁实例对象,一种锁类对象。

    锁实例对象就是当多个线程同时操作这个实例对象的时候必须先获取锁,如果无法获取锁,则必须处于等待状态,而和锁类对象区别是,当多个线程同时操作的时候,任何以这个类对象实例化的对象都要获取锁才能操作。

    二  wait、notify已经notifyAll

    wait、notify、notifyAll是Object对象的属性,并不属于线程。我们先解释这三个的一个很重要的概念

    wait:使持有该对象的线程把该对象的控制权交出去,然后处于等待状态(这句话很重要,也就是说当调用wait的时候会释放锁并处于等待的状态)

    notify:通知某个正在等待这个对象的控制权的线程可以继续运行(这个就是获取锁,使自己的程序开始执行,最后通过notify同样去释放锁,并唤醒正在等待的线程)

    notifyAll:会通知所有等待这个对象控制权的线程继续运行(和上面一样,只不过是唤醒所有等待的线程继续执行)

    三  一个跑步比赛的线程同步测试

     3.1、奔跑者线程

    package simm.learning.biztest.threads;
    
    import java.util.Date;
    import java.util.UUID;
    
    /**
     * 奔跑的人
     */
    public class Runner extends Thread {
        private FireFlag _flag;
        private UUID uuid;
        public Runner(FireFlag flag){
            uuid = UUID.randomUUID();
            Date  dt = new Date();
            System.out.println("奔跑者["+uuid.toString()+"]加入队列..."+FireTest.ft.format(dt) +","+dt.getTime());
            _flag = flag;
        }
        @Override
        public void run() {
            _flag.waitForFire(uuid);
            Date  dt = new Date();
            System.out.println("奔跑者["+uuid.toString()+"]已出发..."+FireTest.ft.format(dt) +","+dt.getTime());
        }
    }

     3.2、开跑信号量

    package simm.learning.biztest.threads;
    
    import java.util.Date;
    import java.util.UUID;
    
    /**
     * 开跑标志位
     */
    public class FireFlag {
        private volatile boolean fired = false;
        public synchronized void waitForFire(UUID id){
            Date  dt = new Date();
            System.out.println("奔跑者["+id.toString()+"]准备就绪..."+FireTest.ft.format(dt) +","+dt.getTime());
            while (!fired){
                try {
                   wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        public synchronized void go(){
            fired = true;
            notifyAll();
        }
    }

     3.3、比赛现场

    package simm.learning.biztest.threads;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    /**
     * 跑步比赛测试
     */
    public class FireTest {
        public static SimpleDateFormat ft = new SimpleDateFormat ("HH:mm:ss.SSS");
    
        public static void main(String[] args) throws InterruptedException {
            FireFlag flag = new FireFlag();
            for(int i=0;i<10;i++){
                Thread.sleep(500L);
                new Runner(flag).start();
            }
            Thread.sleep(3000L);
            System.out.println("go before-"+ft.format(new Date()));
            flag.go();
            System.out.println("go after-"+ft.format(new Date()));
        }
    }

     3.4、开跑情况测试结果反馈

  • 相关阅读:
    使用NBU进行oracle异机恢复
    mycat偶尔会出现JVM报错double free or corruption并崩溃退出
    exp导出数据时丢表
    service_names配置不正确,导致dg创建失败
    XML概念定义以及如何定义xml文件编写约束条件java解析xml DTD XML Schema JAXP java xml解析 dom4j 解析 xpath dom sax
    HTTP协议简介详解 HTTP协议发展 原理 请求方法 响应状态码 请求头 请求首部 java模拟浏览器客户端服务端
    java集合框架容器 java框架层级 继承图结构 集合框架的抽象类 集合框架主要实现类
    【JAVA集合框架一 】java集合框架官方介绍 Collections Framework Overview 集合框架总览 翻译 javase8 集合官方文档中文版
    java内部类深入详解 内部类的分类 特点 定义方式 使用
    再谈包访问权限 子类为何不能使用父类protected方法
  • 原文地址:https://www.cnblogs.com/MrSi/p/9645137.html
Copyright © 2011-2022 走看看