博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java 线程安全问题
阅读量:5205 次
发布时间:2019-06-14

本文共 11999 字,大约阅读时间需要 39 分钟。

线程安全问题产生原因:
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
 

转载于:https://www.cnblogs.com/xiarongjin/p/8309004.html

你可能感兴趣的文章
架构图-模型
查看>>
sql常见面试题
查看>>
jQuery总结第一天
查看>>
Java -- Swing 组件使用
查看>>
Software--Architecture--DesignPattern IoC, Factory Method, Source Locator
查看>>
poj1936---subsequence(判断子串)
查看>>
黑马程序员_Java基础枚举类型
查看>>
【redis4 】
查看>>
shell文件查找和压缩命令
查看>>
[ python ] 练习作业 - 2
查看>>
一位90后程序员的自述:如何从年薪3w到30w!
查看>>
HDU-1242-Rescue
查看>>
在.net core上使用Entity FramWork(Db first)
查看>>
obiee11g中关闭缓存
查看>>
Eclipse中如何开启断言(Assert),方法有二
查看>>
System.Net.WebException: 无法显示错误消息,原因是无法找到包含此错误消息的可选资源程序集...
查看>>
Eclipse注释模板
查看>>
WordCount运行详解
查看>>
压缩图片 待验证
查看>>
冲刺进度条7
查看>>