实例分析java中synchronized关键字用法
2017-02-14 16:32
1011 查看
在多线程运行下,对共享资源的访问要遵循互斥原则,否则会出现资源访问的错误。这时可以使用synchronized关键字对互斥的资源或是方法、对象进行加锁,实例如下:
首先在MyDataGenerator类中有一个偶数数据,以及一个布尔标志数据,代码如下:
默认evenData是每次调用nextEven()方法后值加2,这样就一直使evenData为偶数。然后接下来创建一个用于测试的类MyDataChecker:
在此类中启用多个MyDataChecker线程来执行DataGenerator中的nextEven()方法,在MyDataGenerator加入执行:
启用10个DataChecker线程,共同访问同一个Generator,此时因为nextEven()不是互斥访问,会存在一定的几率在两次evenData+1之间进程进行调度切换,从而evenData变成奇数。从而出现错误:
这时在nextEven()方法前加入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; }
相关文章推荐
- java之this关键字用法实例分析
- java中synchronized关键字作用分析
- java中synchronized关键字作用分析
- Java中 synchronized 关键字的用法
- 举例讲解Java中synchronized关键字的用法
- JAVA线程安全之synchronized关键字的正确用法
- java中synchronized关键字作用分析
- java中synchronized关键字作用分析
- java 中 synchronized关键字 volatile关键字 用法
- java中synchronized关键字作用分析
- JAVA Synchronized 关键字锁实例和锁CLASS对象的区别
- java中synchronized关键字作用分析
- java中synchronized关键字作用分析
- java的synchronized关键字的用法
- java中的synchronized关键字 用法
- java中synchronized关键字作用分析
- java中synchronized关键字作用分析
- java中synchronized关键字作用分析
- java中关键字Synchronized的理解及用法
- JAVA线程安全之synchronized关键字的正确用法