线程的同步

《零基础学Java》


  • 线程的同步

在单线程程序中,每次只能做一件事情,后面的事情需要等待第一件事情完成后才可以进行。为此,Java提供线程同步机制防止多线程编程中抢占资源的问题。

  • 线程安全

    在编写多线程程序时,应该考虑到线程安全问题。

    模拟未考虑到线程安全问题的售票系统:

    public class Demo5 implements Runnable {
        int unm = 10;// 售票池 总票数
    
        public static void main(String[] args) {
            Demo5 demo5 = new Demo5();
            Thread thread1 = new Thread(demo5, "1");// 一号售票机
            Thread thread2 = new Thread(demo5, "2");// 二号售票机
            Thread thread3 = new Thread(demo5, "3");// 三号售票机
            Thread thread4 = new Thread(demo5, "4");// 四号售票机
            thread1.start();// 开启线程
            thread2.start();
            thread3.start();
            thread4.start();
    
        }
    
        @Override
        public void run() {
            while (true) {
                if (unm > 0) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("票数:" + unm--);
                }
            }
        }
    }
    

    模拟未考虑到线程安全问题的售票系统 输出结果:

  • 线程同步机制

    同步块:

    Java中提供了同步机制,可以有效的防止资源冲突。同步机制使用 synchronized关键字 使用该关键字的代码块称为同步块。

    同步块 语法:

    synchronized (Object){
    }
    

    同步块 实例:

    public class Demo6  implements Runnable{
            int unm = 10;// 售票池 总票数
    
            public static void main(String[] args) {
                Demo6 demo6 = new Demo6();
                Thread thread1 = new Thread(demo6, "a1");// 一号售票机
                Thread thread2 = new Thread(demo6, "a2");// 二号售票机
                Thread thread3 = new Thread(demo6, "a2");// 三号售票机
                Thread thread4 = new Thread(demo6, "a4");// 四号售票机
                thread1.start();// 开启线程
                thread2.start();
                thread3.start();
                thread4.start();
    
            }
    
            @Override
            public void run() {
                while (true) {
                    synchronized (this){// 同步代码块,加锁对象为自身
                    if (unm > 0) {
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println("票数:" + unm--);
                    }
                }
            }
        }
    }
    
    同步块 实例输出结果:

    同步方法:

    同步方法就是被 synchronized关键字 修饰的方法。当某个对象调用了同步方法时,该对象的其他方法必须等待该同步方法执行完毕后才能被执行。必须将每个能访问共享资源的方法都修饰为synchronized,否则会出错。

    同步方法 语法:

    synchronized void name(){
    }
    
posted on 2022-04-13 00:20  TeaTracing  阅读(74)  评论(0编辑  收藏  举报