zoukankan      html  css  js  c++  java
  • 线程的同步(协调)synchronized

    【格式】

    同步代码块:synchronized(Object){...} 关键字在代码块前,每次只允许一个线程调用此代码块。

    Object为任何对象(一般用this),每个对象都有一个标志位(0锁住状态,1锁打开状态)。

    同步方法:synchronized void method(){...} 关键字在方法前,每次只允许一个线程调用此方法

    【使用场景】

    多线程访问同一资源时,为防止产生冲突,使用synchronized对该资源(方法、代码块)加锁。

    理解为:多人上同一个厕所,synchronized是门上的锁(0闭、1开)。一个线程运行到synchronized处,要观察锁的状态,如果闭(里面有人在使用),在门口继续等待。当锁为开(里面的运行完毕),则此线程进入使用,并锁上。

    【Runnable接口】

    使用Runnable接口管理多线程:如果不使用同一个接口,则每个线程对象new各自的接口,那么会产生多个厕所(下列中的num数据池),每人一个。脱离了多线程访问同一资源的范畴。

    【条件语句】

    if条件尽量前置,否则,先执行再判断。

    【举例】:通过不同方式购买车票后,查询余票数目。3个线程:手机电脑端、柜台、自助售票机

    class MyThreadRunnalbe implements Runnable {
        int num = 10;//车票总数
    
        public void run() {//线程要执行的任务
            while (true) {
                synchronized (this) {//同步(协调)代码块,加锁
                    if (num > 0) {//条件尽量前置
                        try {
                            Thread.sleep(500);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println(Thread.currentThread().getName() + "购买,余票:" + num--);
                    } else break;
                }
            }
        }
    }
    
    public class Demo {
        public static void main(String[] args) {
            MyThreadRunnalbe mtr = new MyThreadRunnalbe();//创建端口对象(以下3个线程共同使用这1个端口)
            Thread tA = new Thread(mtr, "手机电脑端");// 以该类对象分别实例化4个线程
            Thread tB = new Thread(mtr, "柜台");
            Thread tC = new Thread(mtr, "自助售票机");
    //        //不可以分别new MyThreadRunnalbe(),3个接口使得3个线程各自执行,无法达到有序的目的
    //        Thread tA = new Thread(new MyThreadRunnalbe(), "手机电脑端");
    //        Thread tB = new Thread(new MyThreadRunnalbe(), "柜台");
    //        Thread tC = new Thread(new MyThreadRunnalbe(), "自助售票机");
            tA.start();// 分别启动线程
            tB.start();
            tC.start();
        }
    }

     或者,同步(协调)方法sell()

    class MyThreadRunnalbe implements Runnable {
        int num = 10;//车票总数
    
        public void run() {//线程要执行的任务
            while (true) {
                sell();//调用sell方法
                if (num <= 0) break;
            }
        }
    
        public synchronized void sell() {//创建sell方法,并同步(协调)
    
            if (num > 0) {//条件尽量前置
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "购买,余票:" + num--);
            }
        }
    }
    
    public class Demo {
        public static void main(String[] args) {
            MyThreadRunnalbe mtr = new MyThreadRunnalbe();//创建端口对象(以下3个线程共同使用这1个端口)
            Thread tA = new Thread(mtr, "手机电脑端");// 以该类对象分别实例化4个线程
            Thread tB = new Thread(mtr, "柜台");
            Thread tC = new Thread(mtr, "自助售票机");
    //        //不可以分别new MyThreadRunnalbe(),3个接口使得3个线程各自执行,无法达到有序的目的
    //        Thread tA = new Thread(new MyThreadRunnalbe(), "手机电脑端");
    //        Thread tB = new Thread(new MyThreadRunnalbe(), "柜台");
    //        Thread tC = new Thread(new MyThreadRunnalbe(), "自助售票机");
            tA.start();// 分别启动线程
            tB.start();
            tC.start();
        }
    }
  • 相关阅读:
    AtCoder Beginner Contest 205
    Codeforces Round #725 (Div. 3)
    Educational Codeforces Round 110 (Rated for Div. 2)【A
    Codeforces Round #722 (Div. 2)
    AtCoder Beginner Contest 203(Sponsored by Panasonic)
    AISing Programming Contest 2021(AtCoder Beginner Contest 202)
    PTA 520 钻石争霸赛 2021
    Educational Codeforces Round 109 (Rated for Div. 2)【ABCD】
    AtCoder Beginner Contest 200 E
    Educational Codeforces Round 108 (Rated for Div. 2)【ABCD】
  • 原文地址:https://www.cnblogs.com/xixixing/p/9574008.html
Copyright © 2011-2022 走看看