Java 线程的安全问题及解决方式

线程的安全问题

一.问题提出:

    ①多个线程执行的不确定性引起执行结果不稳定

    ②多线程对数据的共享,造成操作不完整性,破坏数据

  某个执行中的线程操作过程中,尚未完成相关操作时,其他线程参与进来也执行相同的操作,这时就会出现线程安全问题

二.如何解决?

    当一个线程a在操作共享数据时,使其他线程不能参与进来,直到a的相关操作完成时,其他线程才可以操作,即使a被阻塞,也不能被改变

    在java中通过同步机制来解决线程安全问题

三.解决线程安全问题的方式:

方式一:

同步代码块

Synchronized(同步监视器){
     //需被同步的代码
 }

说明:

   操作共享数据的代码即为需被同步的代码,中间不能包多了,也不能包少了,包多包少都会造成线程安全问题

共享数据:

    多个线程共同操作的变量

同步监视器:

即锁,任何一个类的对象都可以充当锁,在Runnable方式中用this代替

助解:

锁对象可以是任何对象,但对于多线程来说必须是同一个对象

在对象中有一个对象头的区域,在对象投中有一个标志位用来存放锁的状态.在对象进入后锁状态由无锁装换为有锁,使得其他对象不能再进入,在所需代码执行完毕后,锁状态又由有锁转换为无锁

要求:

①多个线程必须用同一把锁

②使用同步代码块的方式解决继承Thread类的线程安全问题:

注意:

Thread类中有多个对象,要慎用this充当同步监视器

1.使用static修饰锁

2.synchronized(Window.class)

栗子:

static class Windows implements Runnable {

        @Override
        public void run() {
            while(true){
                synchronized (this){   //采用同步代码块的方式解决线程安全问题
                    if (ticket>0){
                        System.out.println(Thread.currentThread().getName() + ":买票,票号为:" + ticket);
                        ticket--;
                    }else {
                        break;
                    }
                }
            }
        }
    }

synchronized注解;

synchronized修饰方法时,并没有显示的让我们添加锁标注对象,在修饰非静态方法时,锁标志对象默认为this,在修饰静态方法时,锁标志对象是Class类的对象

什么是Class类的对象?

每个类被加载进入内存时,都会为该类创建一个Class类的对象,用于封装类的信息

一个类即使创建多个对象,Class类的对象只有一个

方式二:

同步方法

   ①若操作共享数据的代码完整声明在一个方法中,不妨将此方法声明为公共的

这时我们就可以将操作共享数据的代码提取出来,定义在一个方法中,并使用synchronized修饰方法

  ②使用共享数据的方法解决继承Thread类的线程安全问题

此时需用static修饰方法

pubic static synchronized void show(){

}

同步方法总结:

   1.同步方法仍涉及同步监视器,只是不需要显示声明

  2.非静态同步方法的同步监视器为: this

静态方法同步方法的同步监视器为: 当前类本身

栗子:

static class Windows implements Runnable {

        @Override
        public synchronized void run() {    //采用同步方法的方式解决线程安全问题
            while(true){
                if (ticket>0){
                    System.out.println(Thread.currentThread().getName() + ":买票,票号为:" + ticket);
                    ticket--;
                }else {
                    break;
                }
            }
        }
    }

接下来还有第三种解决线程安全的方式Lock(锁),在我的下篇博客中单独介绍...

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不会写代码的菜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值