• Java 线程安全问题


    线程安全问题产生原因:
    1、多个线程操作共享的数据;
    2、操作共享数据的线程代码有多条。
     
    当一个线程正在执行操作共享数据的多条代码过程中,其它线程也参与了运算,
    就会导致线程安全问题的发生。
    class Ticket extends Thread
    {
        private int num = 100;
        public void run()
        {
            while(num > 0)
            {    
                   try {
                        Thread.currentThread().sleep(10);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
               System.out.println(Thread.currentThread().getName() + "..." + num-- );
            }
        }
    }
    
    public class MyDemo {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            
            Runnable ticket = new Ticket();
            
            Thread t1 = new Thread(ticket);
            Thread t2 = new Thread(ticket);
            Thread t3 = new Thread(ticket);
            Thread t4 = new Thread(ticket);
            
            t1.start();
            t2.start();
            t3.start();
            t4.start();    
        }
    }
    Output:
    Thread-1...11
    Thread-2...10
    Thread-4...9
    Thread-3...8
    Thread-2...7
    Thread-1...6
    Thread-3...5
    Thread-4...4
    Thread-1...2
    Thread-2...3
    Thread-4...1
    Thread-3...0
    Thread-2...-1
    Thread-1...-2
     

    解决思路:

    就是将多条操作共享数据的线程代码封装起来,当有线程在执行这些代码的时候,
    其他线程时不可以参与运算的。
    必须要当前线程把这些代码都执行完毕后,其他线程才可以参与运算。 
     
    在java中,用同步代码块就可以解决这个问题。
     
    同步代码块的格式:
    synchronized(对象)
    {
    需要被同步的代码 ;
    }
    同步的好处:解决了线程的安全问题。
    同步的弊端:相对降低了效率,因为同步外的线程的都会判断同步锁
    同步的前提:同步中必须有多个线程并使用同一个锁。
    Example:
    class Ticket implements Runnable
    {
        private int num = 100;
        Object obj = new Object();
        
        public void run()
        {
            // 如果将同步锁对象obj定义在此处,则会在每一个线程中都创建一个同步锁,
                    //即无法实现线程的同步。
            while(true)
            {
                synchronized(obj)    //同步代码块
                {
                    if(num > 0)
                    {
                        try {
                            Thread.currentThread().sleep(100);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        System.out.println(Thread.currentThread().getName() + "..." + num--);
                    }
                }
            }
            
        }
    
    }
    
    public class MyDemo {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            
            Runnable ticket = new Ticket();
            
            Thread t1 = new Thread(ticket);
            Thread t2 = new Thread(ticket);
            Thread t3 = new Thread(ticket);
            Thread t4 = new Thread(ticket);    
            t1.start();
            t2.start();
            t3.start();
            t4.start();
        }
    }
    Output:
    Thread-2...17
    Thread-2...16
    Thread-2...15
    Thread-2...14
    Thread-2...13
    Thread-2...12
    Thread-3...11
    Thread-3...10
    Thread-3...9
    Thread-3...8
    Thread-3...7
    Thread-3...6
    Thread-3...5
    Thread-3...4
    Thread-3...3
    Thread-3...2
    Thread-3...1
     
    Example:
    class Ticket extends Thread
    {
        private int num = 100;
        Object obj = new Object();
        
        public void run()
        {
            
            while(true)
            {
                synchronized(obj)
                {
                    if(num > 0)
                    {
                        try {
                            Thread.currentThread().sleep(100);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        System.out.println(Thread.currentThread().getName() + "..." + num--);
                    }
                }
            }
            
        }
    
    }
    
    public class MyDemo {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            
            Ticket t1 = new Ticket();
            Ticket t2 = new Ticket();
            Ticket t3 = new Ticket();
            Ticket t4 = new Ticket();
            t1.start();
            t2.start();
            t3.start();
            t4.start();
        }
    }
    Output:
    Thread-3...2
    Thread-1...7
    Thread-2...10
    Thread-0...4
    Thread-3...1
    Thread-2...9
    Thread-1...6
    Thread-0...3
    Thread-1...5
    Thread-0...2
    Thread-2...8
    Thread-2...7
    Thread-0...1
    Thread-1...4
    Thread-1...3
    Thread-2...6
    Thread-2...5
    Thread-1...2
    Thread-2...4
    Thread-1...1
    Thread-2...3
    Thread-2...2
    Thread-2...1
    /*
    同步函数的使用的锁是this;
    同步函数和同步代码块的区别:
    同步函数的锁是固定的this。
    同步代码块的锁是任意的对象。
    建议使用同步代码块。
    */
    class Ticket implements Runnable
    {
        private  int num = 100;
        boolean flag = true;
        public void run()
        {
            if(flag)
                while(true)
                {
                    synchronized(this)
                    {
                        if(num>0)
                        {
                            try{Thread.sleep(10);}catch (InterruptedException e){}                        
                            System.out.println(Thread.currentThread().getName()+".....obj...."+num--);
                        }
                    }
                }
            else
                while(true)
                    this.show();
        }
    
        public synchronized void show()
        {
            if(num>0)
            {
                try{Thread.sleep(10);}catch (InterruptedException e){}
                
                System.out.println(Thread.currentThread().getName()+".....function...."+num--);
            }
        }
    }
    
    class SynFunctionLockDemo 
    {
        public static void main(String[] args) 
        {
            Ticket t = new Ticket();
    
            Thread t1 = new Thread(t);
            Thread t2 = new Thread(t);
    
            t1.start();
            try{Thread.sleep(10);}catch(InterruptedException e){}
            t.flag = false;
            t2.start();
        }
    }
    Output:
    Thread-0.....obj....100
    Thread-0.....obj....99
    Thread-0.....obj....98
    Thread-1.....function....97
    Thread-1.....function....96
    Thread-1.....function....95
    Thread-1.....function....94
    Thread-1.....function....93
    Thread-1.....function....92
    Thread-1.....function....91
    Thread-1.....function....90
    Thread-1.....function....89
    Thread-1.....function....88
    Thread-1.....function....87
    Thread-1.....function....86
    Thread-1.....function....85
    Thread-1.....function....84
    Thread-1.....function....83
    Thread-1.....function....82
    Thread-1.....function....81
    Thread-1.....function....80
    Thread-1.....function....79
    Thread-1.....function....78
    Thread-1.....function....77
    Thread-1.....function....76
    Thread-1.....function....75
    Thread-1.....function....74
    Thread-1.....function....73
    Thread-1.....function....72
    Thread-1.....function....71
    Thread-1.....function....70
    Thread-1.....function....69
    Thread-1.....function....68
    Thread-1.....function....67
    Thread-1.....function....66
    Thread-1.....function....65
    Thread-1.....function....64
    Thread-1.....function....63
    Thread-1.....function....62
    Thread-1.....function....61
    Thread-1.....function....60
    Thread-1.....function....59
    Thread-1.....function....58
    Thread-1.....function....57
    Thread-1.....function....56
    Thread-1.....function....55
    Thread-1.....function....54
    Thread-1.....function....53
    Thread-1.....function....52
    Thread-1.....function....51
    Thread-1.....function....50
    Thread-1.....function....49
    Thread-1.....function....48
    Thread-1.....function....47
    Thread-1.....function....46
    Thread-1.....function....45
    Thread-1.....function....44
    Thread-1.....function....43
    Thread-1.....function....42
    Thread-1.....function....41
    Thread-1.....function....40
    Thread-1.....function....39
    Thread-1.....function....38
    Thread-1.....function....37
    Thread-1.....function....36
    Thread-1.....function....35
    Thread-1.....function....34
    Thread-1.....function....33
    Thread-1.....function....32
    Thread-1.....function....31
    Thread-1.....function....30
    Thread-1.....function....29
    Thread-1.....function....28
    Thread-1.....function....27
    Thread-1.....function....26
    Thread-1.....function....25
    Thread-1.....function....24
    Thread-1.....function....23
    Thread-1.....function....22
    Thread-1.....function....21
    Thread-1.....function....20
    Thread-1.....function....19
    Thread-1.....function....18
    Thread-1.....function....17
    Thread-1.....function....16
    Thread-1.....function....15
    Thread-1.....function....14
    Thread-1.....function....13
    Thread-1.....function....12
    Thread-1.....function....11
    Thread-1.....function....10
    Thread-1.....function....9
    Thread-1.....function....8
    Thread-1.....function....7
    Thread-1.....function....6
    Thread-1.....function....5
    Thread-1.....function....4
    Thread-1.....function....3
    Thread-1.....function....2
    Thread-1.....function....1
     
    /*
    静态的同步函数使用的锁是  该函数所属字节码文件对象 
    可以用 getClass方法获取,也可以用当前  类名.class 表示。
    */
    /* synchronized作用于静态方法和非静态方法的区别: 
     *  非静态方法: 
     *           给对象加锁(可以理解为给这个对象的内存上锁,注意 只是这块内存,其他同类对象都会有各自的内存锁),这时候 
     *          在其他一个以上线程中执行该对象的这个同步方法(注意:是该对象)就会产生互斥 
     *  静态方法:  
     *          相当于在类上加锁(*.class 位于代码区,静态方法位于静态区域,这个类产生的对象公用这个静态方法,所以这块 
     *          内存,N个对象来竞争), 这时候,只要是这个类产生的对象,在调用这个静态方法时都会产生互斥 
    */
    class Ticket implements Runnable
    {
        private static int num = 100;
        boolean flag = true;
        public void run()
        {
    
            if(flag)
                while(true)
                {
                    synchronized(this.getClass())   //  Ticket.class
                    {
                        if(num>0)
                        {
                            try{Thread.sleep(10);}catch (InterruptedException e){}                        
                            System.out.println(Thread.currentThread().getName()+".....obj...."+num--);
                        }
                    }
                }
            else
                while(true)
                    show();
        }
    
        public static synchronized void show()
        {
            if(num>0)
            {
                try{Thread.sleep(10);}catch (InterruptedException e){}
                
                System.out.println(Thread.currentThread().getName()+".....function...."+num--);
            }
        }
    }
    
    class SynFunctionLockDemo 
    {
        public static void main(String[] args) 
        {
            Ticket t = new Ticket();
    
            Thread t1 = new Thread(t);
            Thread t2 = new Thread(t);
    
            t1.start();
            try{Thread.sleep(10);}catch(InterruptedException e){}
            t.flag = false;
            t2.start();
        }
    }
    Output:
    Thread-0.....obj....100
    Thread-1.....function....99
    Thread-1.....function....98
    Thread-0.....obj....97
    Thread-0.....obj....96
    Thread-0.....obj....95
    Thread-0.....obj....94
    Thread-0.....obj....93
    Thread-0.....obj....92
    Thread-0.....obj....91
    Thread-0.....obj....90
    Thread-0.....obj....89
    Thread-0.....obj....88
    Thread-0.....obj....87
    Thread-0.....obj....86
    Thread-0.....obj....85
    Thread-0.....obj....84
    Thread-0.....obj....83
    Thread-0.....obj....82
    Thread-0.....obj....81
    Thread-0.....obj....80
    Thread-0.....obj....79
    Thread-0.....obj....78
    Thread-0.....obj....77
    Thread-0.....obj....76
    Thread-0.....obj....75
    Thread-0.....obj....74
    Thread-0.....obj....73
    Thread-0.....obj....72
    Thread-0.....obj....71
    Thread-0.....obj....70
    Thread-0.....obj....69
    Thread-0.....obj....68
    Thread-0.....obj....67
    Thread-0.....obj....66
    Thread-0.....obj....65
    Thread-0.....obj....64
    Thread-0.....obj....63
    Thread-0.....obj....62
    Thread-0.....obj....61
    Thread-0.....obj....60
    Thread-0.....obj....59
    Thread-0.....obj....58
    Thread-0.....obj....57
    Thread-0.....obj....56
    Thread-0.....obj....55
    Thread-0.....obj....54
    Thread-0.....obj....53
    Thread-0.....obj....52
    Thread-0.....obj....51
    Thread-0.....obj....50
    Thread-0.....obj....49
    Thread-0.....obj....48
    Thread-0.....obj....47
    Thread-0.....obj....46
    Thread-0.....obj....45
    Thread-0.....obj....44
    Thread-0.....obj....43
    Thread-0.....obj....42
    Thread-0.....obj....41
    Thread-0.....obj....40
    Thread-0.....obj....39
    Thread-0.....obj....38
    Thread-0.....obj....37
    Thread-0.....obj....36
    Thread-0.....obj....35
    Thread-0.....obj....34
    Thread-0.....obj....33
    Thread-0.....obj....32
    Thread-0.....obj....31
    Thread-0.....obj....30
    Thread-0.....obj....29
    Thread-0.....obj....28
    Thread-0.....obj....27
    Thread-0.....obj....26
    Thread-0.....obj....25
    Thread-0.....obj....24
    Thread-0.....obj....23
    Thread-0.....obj....22
    Thread-0.....obj....21
    Thread-0.....obj....20
    Thread-0.....obj....19
    Thread-0.....obj....18
    Thread-0.....obj....17
    Thread-0.....obj....16
    Thread-0.....obj....15
    Thread-0.....obj....14
    Thread-1.....function....13
    Thread-1.....function....12
    Thread-1.....function....11
    Thread-1.....function....10
    Thread-1.....function....9
    Thread-1.....function....8
    Thread-1.....function....7
    Thread-1.....function....6
    Thread-1.....function....5
    Thread-1.....function....4
    Thread-1.....function....3
    Thread-1.....function....2
    Thread-1.....function....1
     
  • 相关阅读:
    C# 异步锁
    C#异步编程基础入门总结
    C#异步编程基础入门总结
    C#与数据结构--图的遍历
    C#中IEumerable的简单了解
    C# prism 框架 MVVM框架 Prism系列之事件聚合器
    .NET Core 3 WPF MVVM框架 Prism系列之对话框服务
    C# prism 框架
    TaskAwaiter<TResult> 结构
    利用Eventlog Analyzer分析日志
  • 原文地址:https://www.cnblogs.com/xiarongjin/p/8309004.html
Copyright © 2020-2023  润新知