实例分析java中synchronized关键字用法

在多线程运行下,对共享资源的访问要遵循互斥原则,否则会出现资源访问的错误。这时可以使用synchronized关键字对互斥的资源或是方法、对象进行加锁,实例如下:
首先在MyDataGenerator类中有一个偶数数据,以及一个布尔标志数据,代码如下:

public class MyDataGenerator {
    private int evenData;
    private boolean cancel;

    MyDataGenerator() {
        this.evenData = 0;
        this.cancel = false;
    }

    public int nextEven() {
        evenData ++;      // 出错的位置
        evenData ++;
        return evenData;
    }

    public boolean getCancel() {
        return cancel;
    }

    public int getEvenData() {
        return evenData;
    }

    public void cancel() {
        cancel = true;
        System.out.println("Now the data is: " + evenData);
    }
}

默认evenData是每次调用nextEven()方法后值加2,这样就一直使evenData为偶数。然后接下来创建一个用于测试的类MyDataChecker:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class MyDataChecker implements Runnable {
    private MyDataGenerator myDataGenerator;
    private int checkerId;

    MyDataChecker(MyDataGenerator dg, int id) {
        myDataGenerator = dg;
        checkerId = id;
    }

    public void run() {
        while (!myDataGenerator.getCancel()) {
            if (myDataGenerator.nextEven() % 2 != 0) {
                myDataGenerator.cancel();
                System.out.println("Not even number, failure.");
            }
        }
    }

    public static void testDataFailure(MyDataGenerator myDataGenerator, int threadNum) {
        ExecutorService exec = Executors.newCachedThreadPool();
        for (int i = 0; i < threadNum; i++)
            exec.execute(new MyDataChecker(myDataGenerator, i));
        exec.shutdown();
    }

}

在此类中启用多个MyDataChecker线程来执行DataGenerator中的nextEven()方法,在MyDataGenerator加入执行:

public static void main(String[] args) {
        MyDataChecker.testDataFailure(new MyDataGenerator(), 10);
    }

启用10个DataChecker线程,共同访问同一个Generator,此时因为nextEven()不是互斥访问,会存在一定的几率在两次evenData+1之间进程进行调度切换,从而evenData变成奇数。从而出现错误:

Now the data is: 1074
Not even number, failure.

这时在nextEven()方法前加入synchronized关键字可以使进程互斥访问此方法,在使用时加锁,从而不再出错:

public synchronized int nextEven() {
        evenData ++;
        evenData ++;
        return evenData;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值