数据类:

package Thread.MyCommon;

public class Data {

    public int num = 0;

    public synchronized int getEven() {
++num;
Thread.yield();//让另外线程先执行,加大测试效果几率
++num;
return num;
} }

线程类:

package Thread.MyCommon;

public class myThread implements Runnable {

    private Data data;

    public myThread(Data d) {
data = d;
} @Override
public void run() {
while (true)
{
int val = data.getEven();
if (val % 2 != 0) {
System.out.println(val + " not even!");
}
}
} }

主线程类:

package Thread.MyCommon;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; public class Main { public static void main(String[] args) {
Data data=new Data();//多个线程操作的是同一个对象
ExecutorService executorService=Executors.newCachedThreadPool();
for (int i = 0; i < 10; i++) {
executorService.execute(new myThread(data));
}
executorService.shutdown();//关闭线程池,如果不关闭线程池将一直运行。
}
}

------------------------------------------------------------------------------------------

可以将同步代码改用lock方式:

package Thread.MyCommon;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; public class Data { public int num = 0; Lock lock = new ReentrantLock(); public int getEven() {
lock.lock();
try {
++num;
Thread.yield();// 让另外线程先执行,加大测试几率
++num;
return num;// 一定要在unlock之前return,否则数据不同步
} finally {
lock.unlock();
}
// return num;//不能在unlock之后return,否则数据不同步
}
}

或者改成 synchronized (this)

package Thread.MyCommon;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; public class Data { public int num = 0; Lock lock = new ReentrantLock(); public int getEven() {
synchronized (this) {
++num;
Thread.yield();// 让另外线程先执行,加大测试几率
++num;
return num;// 一定要在unlock之前return,否则数据不同步
}
}
}

--------------------------------------------------------------------------

以下写法,虽然已经同步,但是读取方法不能保证数据是同步的偶数

package Thread.MyCommon;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; public class AtomicityTest implements Runnable { private int i = 0; public int getValue() {
return i;
} private synchronized void evenIncrement() {
i++;
Thread.yield();
i++;
} @Override
public void run() {
while (true)
evenIncrement();
} public static void main(String[] args) {
ExecutorService exec = Executors.newCachedThreadPool();
AtomicityTest at = new AtomicityTest();
exec.execute(at);
while (true) {
int val = at.getValue();
if (val % 2 != 0) {
System.out.println(val);
System.exit(0);
}
}
}
}

Java多线程之简单的线程同步实例的更多相关文章

  1. Java多线程——<三>简单的线程执行:Executor

    一.概述 按照<Java多线程——<一><二>>中所讲,我们要使用线程,目前都是显示的声明Thread,并调用其start()方法.多线程并行,明显我们需要声明多个 ...

  2. java多线程(2) 线程同步

    我们对线程访问同一份资源的多个线程之间,来进行协调的这个东西,就是线程同步.   例子1:模拟了多个线程操作同一份资源,可能带来的问题: package com.cy.thread; public c ...

  3. Java多线程系列三——实现线程同步的方法

    两种实现线程同步的方法 方法 特性 synchronized 不需要显式地加解锁,易实现 ReentrantLock 需要显式地加解锁,灵活性更好,性能更优秀,结合Condition可实现多种条件锁 ...

  4. Java多线程(二) —— 线程安全、线程同步、线程间通信(含面试题集)

    一.线程安全 多个线程在执行同一段代码的时候,每次的执行结果和单线程执行的结果都是一样的,不存在执行结果的二义性,就可以称作是线程安全的. 讲到线程安全问题,其实是指多线程环境下对共享资源的访问可能会 ...

  5. Java多线程(一) —— 线程的状态详解

    一.多线程概述  1. 进程 是一个正在执行的程序.是程序在计算机上的一次运行活动. 每一个进程执行都有一个执行顺序.该顺序是一个执行路径,或者叫一个控制单元. 系统以进程为基本单位进行系统资源的调度 ...

  6. Java多线程(五)线程的生命周期

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

  7. java多线程中并发集合和同步集合有哪些?区别是什么?

    java多线程中并发集合和同步集合有哪些? hashmap 是非同步的,故在多线程中是线程不安全的,不过也可以使用 同步类来进行包装: 包装类Collections.synchronizedMap() ...

  8. “全栈2019”Java多线程第二十一章:同步代码块产生死锁的例子

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

  9. java多线程(三)线程的安全问题

    1.1. 什么是线程安全 如果有多个线程同时运行同一个实现了Runnable接口的类,程序每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的:反之,则是线程不 ...

随机推荐

  1. SpringMVC给外部资源加版本号避免缓存

    一.属性文件:version.properties ->内容:version=201608  二.java代码 public class configVersion implements Ser ...

  2. 搭建最简单的SpringMVC框架(使用maven)

    本文说明:本文介绍使用maven搭建SpringMVC最简单的框架程序过程,适合初学者上手. 下载链接 点此进入下载链接 1.创建一个maven webapp工程. 2.修改WEB-INF目录下的we ...

  3. Notepad++ Emmet安装方法教程

    Notepad++ Emmet安装后出现 unknown exception提示插件无效Python Script Plugin did not accept the script.以下为记录解决方法 ...

  4. [机器学习之13]降维技术——主成分分析PCA

    始终贯彻数据分析的一个大问题就是对数据和结果的展示,我们都知道在低维度下数据处理比较方便,因而数据进行简化成为了一个重要的技术.对数据进行简化的原因: 1.使得数据集更易用使用.2.降低很多算法的计算 ...

  5. OpenJudge计算概论-细菌的战争

    /*====================================================================== 细菌的战争 总时间限制: 1000ms 内存限制: 6 ...

  6. mysql 获取一个表中缺失的最小编号

    select count(*),t1.`name` from test_id t1INNER JOIN test_id t2on t1.id >= t2.idgroup by t1.id,t1. ...

  7. Windows命令行查看文件的MD5

    certutil -hashfile D:\apache-tomcat-7.0.68-windows-x64.zip  MD5certutil -hashfile D:\apache-tomcat-7 ...

  8. C# MDI 子窗体被父窗体控件挡住

    using System.Runtime.InteropServices; [DllImport("user32")] public static extern int SetPa ...

  9. C/C++中产生随机数(rand,srand用法)

    计算机的随机数都是由伪随机数,即是由小M多项式序列生成的,其中产生每个小序列都有一个初始值,即随机种子.(注意: 小M多项式序列的周期是65535,即每次利用一个随机种子生成的随机数的周期是65535 ...

  10. sql访注入

    http://www.dewen.org/q/6154/java%E7%A8%8B%E5%BA%8F%E9%98%B2%E6%AD%A2sql%E6%B3%A8%E5%85%A5%E7%9A%84%E ...