java多线程编程18-22(实列变量共享导致的“非线程安全”问题与相应的解决方案)

//实列变量共享导致的“非线程安全”问题与相应的解决方案

// 自定义线程类中的实例变量针对其他线程可以有共享与不共享之分,这在多个线程直接交互是非常重要的

//1. 不共享数据的情况

public class TestDemo extends Thread{
    private int count =5;

    public TestDemo(String name){
        super();
        this.setName(name);
    }

    @Override
    public void run() {
        super.run();
        while (count>0){
            count --;
            System.out.println("由 "+this.currentThread().getName()+" 计算,count="+count);
        }
    }
}
//三个线程都有自己的变量
class Run{
    public static void main(String[] args) {
        TestDemo a =new TestDemo("A");
        TestDemo b =new TestDemo("B");
        TestDemo c =new TestDemo("C");
        a.start();
        b.start();
        c.start();
    }
}

//如何实现三个线程共同对一个count 变量进行减法操作,代码该如何设计?
//共享数据的情况:

class Mythread4 extends Thread{
    private int count =5;

    public Mythread4(String name){
        super();
        this.setName(name);
    }
    @Override
    public void run() {
        super.run();
            count --;
            System.out.println("由 "+this.currentThread().getName()+" 计算,count="+count);
    }

}
// 线程A和B输出的结果是一致的 说明A和B同时对count进行处理,产生"非线程安全"问题
// 而我们想要的得到的输出结果是依次递减的

//出现非线程安全的情况是因为在某些JVM中,count-- 的操作要分解成如下三步(执行这三个过程的
// 步骤的过程中会被其他线程打断)
// 1.取得原有的count 值
// 2.计算count-1
// 3.对count 进行重新赋值
// 在这三个步骤中:如果有多个线程同时访问,那么很大概率会出现非线程安全的问题

//出现非线程安全的情况是多个线程操作同一个对象的同一个实例变量,导致值不准确.

class Run1{
    public static void main(String[] args) {
        Mythread4 a =new Mythread4("A");
        Mythread4 b =new Mythread4("B");
        Mythread4 c =new Mythread4("C");
        Mythread4 d =new Mythread4("D");
        Mythread4 e =new Mythread4("E");
        a.start();
        b.start();
        c.start();
        d.start();
        e.start();
    }
}

//这时就需要在多个线程之间进行同步操作

class Mythread5 extends Thread{
    private int count =5;

    public Mythread5(String name){
        super();
        this.setName(name);
    }
    @Override
    public synchronized void run() {
        super.run();
        count --;
        System.out.println("由 "+this.currentThread().getName()+" 计算,count="+count);
    }

}
//通过run方法面前加入syncronized 关键字,使多个线程在执行run方法时,以排队的方式处理.
// 一个线程在调用run方法前,需要先判断run方法有没有上锁,如果上锁说明有其他线程在调用run方法
//必须等其他线程调用结束后才可以执行run方法

//使用syncronized 关键字修饰的方法称为”同步方法",可以用来对方法内部的全部代码进行枷锁,
// 而枷锁的这段代码称为“互斥区”或者“临界区”.


class Run2{
    public static void main(String[] args) {
        Mythread5 a =new Mythread5("A");
        Mythread5 b =new Mythread5("B");
        Mythread5 c =new Mythread5("C");
        Mythread5 d =new Mythread5("D");
        Mythread5 e =new Mythread5("E");
        a.start();
        b.start();
        c.start();
        d.start();
        e.start();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值