1、synchronized保证同步

先看一个生成偶数的类

  1. <span style="font-size:16px;">package demo.thread;
  2. /**
  3. *这是一个int生成器的抽象类
  4. *
  5. */
  6. public abstract class IntGenerator {
  7. private volatile boolean canceled = false;
  8. public abstract int next();
  9. public void cancel() {
  10. canceled = true;
  11. }
  12. public boolean isCanceled() {
  13. return canceled;
  14. }
  15. }
  16. </span>
  1. <span style="font-size:16px;">/*
  2. * 产生偶数
  3. */
  4. class EvenGenerator extends IntGenerator {
  5. private int currentEvenValue = 0;
  6. String s = "";
  7. @Override
  8. public int next() {
  9. <span style="color:#ff0000;">synchronized </span>(s) {
  10. ++currentEvenValue;
  11. ++currentEvenValue;
  12. return currentEvenValue;
  13. }
  14. }
  15. //  //这样也可以
  16. //  public <span style="color:#ff0000;">synchronized </span>int next() {
  17. //          ++currentEvenValue;
  18. //          ++currentEvenValue;
  19. //          return currentEvenValue;
  20. //  }
  21. }</span>

注意到在产生偶数是要加同步锁,否则可能线程1刚好执行了一句++currentEvenValue;操作,就被线程2抢去了cpu,此时线程2执行return currentEvenValue;这时返回的就是一个奇数。加synchronized
就是两个线程同时只能一个线程执行synchronized 块的代码。

测试代码:

  1. <span style="font-size:16px;">package demo.thread;
  2. import java.util.concurrent.ExecutorService;
  3. import java.util.concurrent.Executors;
  4. /*
  5. * 消费数字
  6. */
  7. public class EvenChecker implements Runnable {
  8. private IntGenerator generator;
  9. private final int id;
  10. public EvenChecker(IntGenerator g, int ident) {
  11. generator = g;
  12. id = ident;
  13. }
  14. public void run() {
  15. while (!generator.isCanceled()) {
  16. int val = generator.next();
  17. if (val % 2 != 0) {//如果不是偶数
  18. System.out.println(val + " not enen!");
  19. generator.cancel();
  20. }
  21. }
  22. }
  23. public static void test(IntGenerator gp, int count) {
  24. ExecutorService exec = Executors.newCachedThreadPool();
  25. for (int i = 0; i < count; i++)
  26. exec.execute(new EvenChecker(gp, i));
  27. exec.shutdown();
  28. }
  29. public static void test(IntGenerator gp) {
  30. test(gp, 10);
  31. }
  32. public static void main(String[] args) {
  33. test(new EvenGenerator());
  34. }
  35. }</span>

分析:如果产生偶数的类未加synchronized,那么测试程序将会出现奇数导致退出程序。

2、volatile表示原子性,可见性。

对于多个线程之间共享的变量,每个线程都有自己的一份拷贝,当线程1改变变量值时,其他线程并不马上知道该变量值改变了,volatile就保证了变量值对各个线程可见,一个线程改变该值,马上其他线程中该值也改变。原子性表明操作不可中断,如基本变量赋值。

代码示例:

  1. <span style="font-size:16px;">package demo.thread;
  2. public class VolatileDemo implements Runnable {
  3. private volatile int i = 0;//volatile设置可见性
  4. public synchronized  int getValue() {
  5. return i;
  6. }
  7. private synchronized void enenIncrement() {
  8. i++;
  9. i++;
  10. }
  11. @Override
  12. public void run() {
  13. while (true)
  14. enenIncrement();
  15. }
  16. public static void main(String[] args) {
  17. VolatileDemo at = new VolatileDemo();
  18. new Thread(at).start();
  19. while (true) {
  20. int val = at.getValue();
  21. if (val % 2 != 0) {//出现奇数,退出程序
  22. System.out.println(val+" is not enen!");
  23. System.exit(0);
  24. }
  25. }
  26. }
  27. }
  28. </span>

注意i++操作并不是原子行操作,getValue() 方法也要加synchronized 。

java多线程总结四:volatile、synchronized示例的更多相关文章

  1. Java多线程(四)—— synchronized关键字续

    1.synchronized原理 在java中,每一个对象有且仅有一个同步锁.这也意味着,同步锁是依赖于对象而存在.当我们调用某对象的synchronized方法时,就获取了该对象的同步锁.例如,sy ...

  2. Java多线程核心技术(四)Lock的使用

    本文主要介绍使用Java5中Lock对象也能实现同步的效果,而且在使用上更加方便. 本文着重掌握如下2个知识点: ReentrantLock 类的使用. ReentrantReadWriteLock ...

  3. Java多线程(四)java中的Sleep方法

    点我跳过黑哥的卑鄙广告行为,进入正文. Java多线程系列更新中~ 正式篇: Java多线程(一) 什么是线程 Java多线程(二)关于多线程的CPU密集型和IO密集型这件事 Java多线程(三)如何 ...

  4. “全栈2019”Java多线程第四章:设置和获取线程名称

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  5. java多线程之内存可见性-synchronized、volatile

    1.JMM:Java Memory Model(Java内存模型) 关于synchronized的两条规定: 1.线程解锁前,必须把共享变量的最新值刷新到主内存中 2.线程加锁时,将清空工作内存中共享 ...

  6. java多线程中的volatile和synchronized

    package com.chzhao; public class Volatiletest extends Thread { private static int count = 0; public ...

  7. java多线程系列(四)---Lock的使用

    Lock的使用 前言:本系列将从零开始讲解java多线程相关的技术,内容参考于<java多线程核心技术>与<java并发编程实战>等相关资料,希望站在巨人的肩膀上,再通过我的理 ...

  8. java多线程(3)---synchronized、Lock

    synchronized.Lock 一.概述 1.出现线程不安全的原因是什么? 如果我们创建的多个线程,存在着共享数据,那么就有可能出现线程的安全问题:当其中一个线程操作共享数据时,还未操作完成,另外 ...

  9. java多线程系列(四)---ReentrantLock的使用

    Lock的使用 前言:本系列将从零开始讲解java多线程相关的技术,内容参考于<java多线程核心技术>与<java并发编程实战>等相关资料,希望站在巨人的肩膀上,再通过我的理 ...

  10. java多线程:线程同步synchronized(不同步的问题、队列与锁),死锁的产生和解决

    0.不同步的问题 并发的线程不安全问题: 多个线程同时操作同一个对象,如果控制不好,就会产生问题,叫做线程不安全. 我们来看三个比较经典的案例来说明线程不安全的问题. 0.1 订票问题 例如前面说过的 ...

随机推荐

  1. windows环境下mysql忘记密码如何重置

    本文主要是针对mysql重置密码过程中出现“mysqld不是内部命令或外部命令”的问题而写的.网上有很多关于mysql忘记密码了如何找回的文章,但是很多说的都不够详细,特别是还要用到DOS命令,可能这 ...

  2. Java中finalize方法用途何在?

    package thinking.in.java.demo; /* * finalize的用途何在? * *本例的终止条件是L所有的Book对象在被当做垃圾回收前都应该被签入.但是在main方法中 * ...

  3. A Tour of Go Exercise: HTTP Handlers

    Implement the following types and define ServeHTTP methods on them. Register them to handle specific ...

  4. 锋利的jquery第二版学习笔记

    jquery系统学习笔记 一.初识:jquery的优势:1.轻量级(压缩后不到30KB)2.强大的选择器(支持css1.css2选择器的全部 css3的大部分 以及一些独创的 加入插件的话还可支持XP ...

  5. (Map)利用Map,完成下面的功能:  从命令行读入一个字符串,表示一个年份,输出该年的世界杯冠军是哪支球队。如果该 年没有举办世界杯,则输出:没有举办世界杯。  附:世界杯冠军以及对应的夺冠年份,请参考本章附录。 附录 (Map)在原有世界杯Map 的基础上,增加如下功能: 读入一支球队的名字,输出该球队夺冠的年份列表。 例如,读入“巴西”,应当输出 1958 1962 1970 1

    package homework001; import java.util.HashMap; import java.util.Scanner; public class Map { public s ...

  6. server2008服务器iis设置的一些经验

    安装顺序会有一定得影响,如果是先安装IIS,再安装.NET Framework,系统应该可以正常解析.aspx页面:但是,如果是先安装了.NET Framework,再安装IIS,则会由于相关的IIS ...

  7. iOS开发——高级技术&二维码功能的实现

    二维码功能的实现 ZBarSDK,一个比较优秀的开源项目,使用起来也很简单. ZBarSDK是一个开源的SDK,可从这里下载到源码,该SDK实现了识别和读取各种条形码,包括EAN-13/UPC-A, ...

  8. sql server char nchar nvarchar varchar之間的區別

    char存储固定长度的字符串,最大长度为8000个字节. varchar存储可变长度的字符串.最大长度为8000个字节. nchar存储固定长度的Unicode字符串,最大长度为4000个字符. nv ...

  9. 句柄(Handle)

    1.句柄是什么?    在windows中,句柄是和对象一一对应的32位无符号整数值.对象可以映射到唯一的句柄,句柄也可以映射到唯一的对象.2.为什么我们需要句柄?     更准确地说,是window ...

  10. C#_delegate - 调用列表

    using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Dele ...