Java多线程-线程安全

1. 数据不共享的状况html

在探讨数据共享的话题前,先来看看数据不共享的状况,每个线程里面的数据都是独立的,就像下面的例子,3个线程,每个线程本身对本身的数据进行扣减,直到0为止安全

public class TestThread { public static void main(String[] args) { MyThread myThread_A = new MyThread("A"); MyThread myThread_B = new MyThread("B"); MyThread myThread_C = new MyThread("C"); myThread_A.start(); myThread_B.start(); myThread_C.start(); } } class MyThread extends Thread { private int count = 5; private String name; public MyThread(String name) { this.name = name; } @Override public void run() { // super.run();

        while (count != 0) { System.out.println(name + " = " + count); count--; } } }

 

运行结果:多线程

 

2. 数据共享的状况ide

这里有一段测试代码,看看共享数据的结构,按照理想的状况下,MyRunnable只实例了一次,因此里面的count=5将会被扣减5次,打印的结果应该是,5,4,3,2,1,由于这里有5个线程,每次调用run的时候,都会减去1,可是结果,确实有点出乎意外....并且每一次执行的结果都不同函数

public class TestThread { public static void main(String[] args) { //新建一个带有Runnable接口的类
        MyRunnable myRunnable = new MyRunnable(); //新建5个线程,但使用了同一个Runnable实例对象,意味着里面的数据是共享的 //这里的Thread(Runnable,String)是一个构造函数,第一次参数为Runnable接口,第二个为线程名称
        Thread thread_A = new Thread(myRunnable,"A"); Thread thread_B = new Thread(myRunnable,"B"); Thread thread_C = new Thread(myRunnable,"C"); Thread thread_D = new Thread(myRunnable,"D"); Thread thread_E = new Thread(myRunnable,"E"); thread_A.start(); thread_B.start(); thread_C.start(); thread_D.start(); thread_E.start(); } } class MyRunnable implements Runnable { private int count = 5; public MyRunnable() { } @Override public void run() { // super.run();
        System.out.println("当前线程名称" + Thread.currentThread().getName() + " = " + count); count--; } }

 

运行结果1:测试

 

运行结果2:this

 

 

运行结果3:spa

 

 

3.线程不安全线程

通过上面的例子隐身出了一个问题,就是线程安全问题,在实际场景当中,这是一个很是危险的问题,例如在双11,秒杀,活动中,不少买家同时在0点的时候按购买,但货品只有1个,很明显这里就是多线程处理同一个数据(货品库存量),那若是在线程不安全的状况下,会出现更上面例子同样的状况,两我的同一时间都在对同一个数字进行处理,结果有多是,多名买家同时得到这个商品。3d

为何这样呢,主要缘由是count--这个代码,通常状况,这行代码作了3个动做

  1. 获取count当前的值
  2. 对count的值进行-1的动做
  3. 对count从新赋值

那问题很明显就出在第一步,假如A线程运行到这一行代码获取到count的值为5,接下来,B线程抢到CPU的使用前,他也执行到了这行代码,获取count的值也是5,由于A线程尚未进行-1的操做

 

4.线程安全

那怎么办呢,关键字synchronized,在run方法前加上这句的代码就能够达到排队执行方法的做用了,意思就是说,在执行run代码的时候,线程先查看当前代码块有没有钥匙,若是有钥匙,便可进入这扇门(代码块),而后执行里面的内容,执行完以后就会把钥匙交出来,由下一个抢到钥匙的人进入,并执行里面的内容。在这个抢钥匙的过程当中是人人平等,谁先抢到钥匙,谁先进入。咱们叫这块区域“互斥区”。

class MyRunnable implements Runnable { private int count = 5; public MyRunnable() { } @Override synchronized public void run() { // super.run();
        System.out.println("当前线程名称" + Thread.currentThread().getName() + " = " + count); count--; } }

 

运行结果1:

 

运行结果2:

 

原文出处:https://www.cnblogs.com/oscar1987121/p/10220639.html

相关文章
相关标签/搜索