zoukankan      html  css  js  c++  java
  • java如何解决线程安全问题

    1. 方式一:同步代码块
    synchroized(同步监视器的对象){
    需要被同步的代码
    }
    package threadtest;
    //使用同步代码块实现Runable接口的线程
    public class Ruanble {
        
        public static void main(String[] args) {
            //创建实现类的对象
            Num num=new Num();
            //将此对象作为参数传递给Thread类的构造器,创建Thread类的对象
            Thread thread1 =new Thread(num);
            Thread thread2 =new Thread(num);
            Thread thread3 =new Thread(num);
            //调用start()启动创建的Thread对象
            
            thread1.setName("线程一");
            thread2.setName("线程二");
            thread3.setName("线程三");
            
            thread1.start();
            thread2.start();
            thread3.start();
        }
    }
    //创建一个类实现Runable接口
    class Num implements Runnable{
        int ticket=100;
        //定义同步监视器,多个线程共同使用唯一的同步监视器
        Object obj=new Object();
        //重写run方法
        @Override
        public void run() {
        while (true) {
            synchronized (obj) {
                if (ticket>0) {
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()  +"开始售票,票号为"+   ticket);
                    ticket--;
                }else {
                    break;
                }
            }
        
         }
        }
    }
    package threadtest;
    //同步代码块实现继承Thread的线程
    public class ThreadTest {
    
        public static void main(String[] args) {
            //创建子类对象
            EvenThread e1=new EvenThread();
            EvenThread e2=new EvenThread();
            EvenThread e3=new EvenThread();
            //调用线程的start()启动
            e1.setName("票口一");
            e2.setName("票口二");
            e3.setName("票口三");
            
            e1.start();
            e2.start();
            e3.start();
        }
        
    
        
    }
    
    //创建一个类继承与Thread类
    class EvenThread extends Thread{
        static int ticket=100;
        //定义同步监视器,多个线程共同使用唯一的同步监视器
        static Object obj=new Object();
        //重写run方法
        @Override
        public void run() {
        while (true) {
            //synchronized (obj) {//方式一,确保同步监视器唯一
                synchronized (EvenThread.class) {//EvenThread.class是唯一的
                if (ticket>0) {
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()  +"开始售票,票号为"+   ticket);
                    ticket--;
                }else {
                    break;
                }
            }
        
         }
        }
    }

    说明:共享数据------多个线程共同操作的数据

            需要被同步的代码块,纪委操作共享的代码

            同步监视器,俗称锁,任何一个类都可以充当同步监视器,但是,要求多个线程共用一个监视器

    1. 方式二:同步方法:如果操作共享数据的代码,完整的声明在相依的方法中,着我们可以考虑将此方法作为同步方法来写
    2. 非静态的同步方法的默认监视器是this,不能修改
    3. 静态的同步方法的监视器是当前类本身,不能修改
    package threadtest;
    //创建同步方法实现Runable的线程
    public class Ruanble {
        
        public static void main(String[] args) {
            //创建实现类的对象
            Num num=new Num();
            //将此对象作为参数传递给Thread类的构造器,创建Thread类的对象
            Thread thread1 =new Thread(num);
            Thread thread2 =new Thread(num);
            Thread thread3 =new Thread(num);
            //调用start()启动创建的Thread对象
            
            thread1.setName("线程一");
            thread2.setName("线程二");
            thread3.setName("线程三");
            
            thread1.start();
            thread2.start();
            thread3.start();
        }
    }
    //创建一个类实现Runable接口
    class Num implements Runnable{
        int ticket=100;
        //定义同步监视器,多个线程共同使用唯一的同步监视器
        Object obj=new Object();
        //重写run方法
        @Override
        public void run() {
        while (true) {
          push();
         }
        }
        //同步方法
        public synchronized void push() {//这里有默认的同步监视器this,是唯一的
            if (ticket>0) {
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()  +"开始售票,票号为"+   ticket);
                ticket--;
            }
        }
    }

    //使用同步方法的来写继承Thread类的

    package threadtest;
    
    public class ThreadTest {
    
        public static void main(String[] args) {
            //创建子类对象
            EvenThread e1=new EvenThread();
            EvenThread e2=new EvenThread();
            EvenThread e3=new EvenThread();
            //调用线程的start()启动
            e1.setName("票口一");
            e2.setName("票口二");
            e3.setName("票口三");
            
            e1.start();
            e2.start();
            e3.start();
        }
        
    
        
    }
    
    //创建一个类继承与Thread类
    class EvenThread extends Thread{
        static int ticket=100;
        //定义同步监视器,多个线程共同使用唯一的同步监视器
        static Object obj=new Object();
        //重写run方法
        @Override
        public void run() {
        while (true) {
            push();
         }
        }
        //public synchronized void push() {//此时不加static,会在new EvenThred对象是,导致同步监视器不是唯一的,故加上static,让它先于类的创建而创建
            public synchronized static  void push(){
            if (ticket>0) {
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()  +"开始售票,票号为"+   ticket);
                ticket--;
            }
        }
    }

     方式三使用lock锁来确保安全,见下篇博客:链接---->

    https://www.cnblogs.com/ylblikestudyJava/p/12378013.html

  • 相关阅读:
    firstResponder
    形而上学
    du -h
    数据本地存贮与数据结构(对象)
    RFC
    oc语言源代码
    HTTP1.1协议中文版-RFC2616
    如何提高团队协作的效率
    iOS应用架构谈 开篇
    nginx版本如何选择?
  • 原文地址:https://www.cnblogs.com/ylblikestudyJava/p/12377269.html
Copyright © 2011-2022 走看看