• 多线程2—java


    ①double check 实现同步 避免超卖

    代码布局:

    在这里插入图片描述

    运行结果:

    超卖的情况:

    在这里插入图片描述

    超卖情况的解决:

    在这里插入图片描述

    代码:

    SalesTicketTask :
    package com.test2;
    
    public class SalesTicketTask implements Runnable{
        //卖票20张
        private int ticket=20;
    
        @Override
        public void run() {
            while(ticket>0){
                synchronized (this){
                    //double check 实现同步 避免超卖
                    if(ticket>0){
                        try {
                            //线程休眠
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println(Thread.currentThread().getName()+"卖票一张,还剩"+(--ticket));
                    }
                }
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    Test :
    package com.test2;
    
    public class Test {
        public static void main(String[] args) {
            //创建售票任务
            SalesTicketTask salesTicketTask=new SalesTicketTask();
            new Thread(salesTicketTask,"张三").start();
            new Thread(salesTicketTask,"李四").start();
            new Thread(salesTicketTask,"王五").start();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    ②创建ReentrantLock锁对象

    代码布局:

    在这里插入图片描述

    运行结果:

    在这里插入图片描述

    代码:

    SalesTicketTask :
    package com.test3;
    
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class SalesTicketTask implements Runnable{
        //卖票20张
        private int ticket=20;
        //创建ReentrantLock锁对象
        private Lock lock=new ReentrantLock();
    
        @Override
        public void run() {
            while(ticket>0){
                lock.lock();
                try {
                    //double check 实现同步 避免超卖
                    if(ticket>0){
                        try {
                            //线程休眠
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println(Thread.currentThread().getName()+"卖票一张,还剩"+(--ticket));
                    }
                }finally {
                    lock.unlock();
                }
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    Test :
    package com.test3;
    
    public class Test {
        public static void main(String[] args) {
            SalesTicketTask salesTicketTask=new SalesTicketTask();
            new Thread(salesTicketTask,"张三").start();
            new Thread(salesTicketTask,"李四").start();
            new Thread(salesTicketTask,"王五").start();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    通过sleep休眠来控制线程执行次序

    代码布局及结果:

    在这里插入图片描述

    代码:

    Test :
    package com.test4;
    
    public class Test {
        public static void main(String[] args) {
    
            Thread t1=new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("aaaaa");
                    try {
                        //通过休眠来控制线程执行次序
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("bbbbb");
                }
            });
    
            Thread t2=new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("ccccc");
                    try {
                        //通过休眠来控制线程执行次序
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("ddddd");
                }
            });
    
            t1.start();
            t2.start();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    定义锁对象:

    代码布局及结果:

    在这里插入图片描述

    代码:

    Test1 :
    package com.test4;
    
    public class Test1 {
        public static void main(String[] args) throws InterruptedException{
            //1.在没有同步代码块的情况下,使用sleep之后,当前线程直接结束对cpu的占用。此时其他线程就有机会获取到cpu资源
            //2.在有同步代码块的情况下,使用sleep之后,当前线程结束对cpu的占用。
            //  但是因为当前线程依旧拿着锁,所以其他线程没有办法执行。
            //  只有当前线程把锁释放之后,其他线程才有机会执行
    
            //定义锁对象
            Object lockObj=new Object();
    
            Thread t1=new Thread(new Runnable() {
                @Override
                public void run() {
                    synchronized (lockObj){
                        System.out.println("aaaaa");
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println("bbbbb");
                    }
                }
            });
    
            Thread t2=new Thread(new Runnable() {
                @Override
                public void run() {
                    synchronized (lockObj){
                        System.out.println("ccccc");
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println("ddddd");
                    }
                }
            });
    
            t1.start();
            t2.start();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    调用锁对象的wait方法,来让线程等待

    代码布局及结果:

    在这里插入图片描述

    代码:

    Test2 :
    package com.test4;
    
    public class Test2 {
        public static void main(String[] args) throws InterruptedException{
            //定义锁对象
            Object lockObj=new Object();
    
            Thread t1=new Thread(new Runnable() {
                @Override
                public void run() {
                    synchronized (lockObj){
                        System.out.println("aaaaa");
                        try {
                            //调用锁对象的wait方法,来让线程等待
                            lockObj.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println("bbbbb");
                    }
                }
            });
    
            Thread t2=new Thread(new Runnable() {
                @Override
                public void run() {
                    synchronized (lockObj){
                        System.out.println("ccccc");
                        //通过notify来唤醒其他线程:让其他线程等着当前线程执行完成,然后其他线程再去执行
                        lockObj.notify();
                        System.out.println("ddddd");
                    }
                }
            });
    
            t1.start();
            t2.start();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
  • 相关阅读:
    springboot中如何使用log4j制作统一的请求日志呢?
    v-for中key的作用与原理
    django学习记录07——订单案例(复选框+ajax请求)
    操作系统漏洞验证及加固-MS08_067漏洞利用与安全加固
    python基于用户兴趣的java影视推荐系统django
    nginx学习第一天
    Java:强引用、软引用、弱引用与虚引用
    东南亚电商市场不欢迎独立站
    Java基于J2EE的流浪动物收容与领养管理系统
    177基于matlab的基于S函数的变步长自适应滤波算法
  • 原文地址:https://blog.csdn.net/Liu_wen_wen/article/details/126901892