深入同步访问共享的可变数据分析
发布时间:2023-05-08 00:16:49
标签:java,同步访问,可变数据
如果对共享的可变数据的访问不能同步,其后果非常可怕,即使这个变量是原子可读写的。
下面考虑一个线程同步方面的问题。对于线程同步,Java类库提供了Thread.stop的方法,但是这个方法并不值得提倡,因为它本质上是不安全的。使用轮询(Polling)的方式会更好,例如下面这段程序。
import java.util.concurrent.TimeUnit;
public class StopThread {
/**
* @param args
*/
private static boolean stopRequested;
public static void main(String[] args)
throws InterruptedException{
Thread backgroundThread = new Thread(new Runnable() {
@Override
public void run() {
int i = 0;
while(!stopRequested){
i++;
System.out.println(i);
}
}
});
backgroundThread.start();
TimeUnit.SECONDS.sleep(1);
stopRequested = true;
}
}
你可能会认为这个程序在运行大约一秒后,由于主线程把stopRequested设成了true,使得后台的新线程停止,其实不然,因为后台线程看不到这个值的变化,所以会一直无线循环下去,这就是没有对数据进行同步的后果。因此让我们用同步的方式来实现这个任务。
import java.util.concurrent.TimeUnit;
public class StopThread {
/**
* @param args
*/
private static boolean stopRequested;
private static synchronized void requestStop(){
stopRequested = true;
}
private static synchronized boolean stopRequested(){
return stopRequested;
}
public static void main(String[] args)
throws InterruptedException{
Thread backgroundThread = new Thread(new Runnable() {
@Override
public void run() {
int i = 0;
while(!stopRequested()){
i++;
System.out.println(i);
}
}
});
backgroundThread.start();
TimeUnit.SECONDS.sleep(1);
requestStop();
}
}
这样就实现了数据的同步,值得注意的是,写方法(requestStop)和读方法(stopRequested)都需要被同步,否则仍然不是真正意义上的同步。
另外,我们可以使用volatile这个变量修饰符来更加简单地完成同步任务。
import java.util.concurrent.TimeUnit;
public class StopThread {
/**
* @param args
*/
private static volatile boolean stopRequested;
public static void main(String[] args)
throws InterruptedException{
Thread backgroundThread = new Thread(new Runnable() {
@Override
public void run() {
int i = 0;
while(!stopRequested){
i++;
System.out.println(i);
}
}
});
backgroundThread.start();
TimeUnit.SECONDS.sleep(1);
stopRequested = true;
}
}


猜你喜欢
- service有两种类型:本地服务(Local Service):用于应用程序内部远程服务(Remote Sercie):用于android
- SpringBoot如何快速配置数据源;有如下两种方式:通过spring-boot-starter-jdbc快速配置数据源自定义数据源Dat
- 这篇文章主要介绍了Spring 事件Application Event原理详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定
- 本文实例为大家分享了Android实现滑动效果的具体代码,供大家参考,具体内容如下坐标系与视图坐标系相辅相成1、坐标系:描述了View在屏幕
- 前言当系统的并发比较高的时候,日志的处理输出也是一种性能的开销负担,所以,选择一个中间件来处理消费日志必不可少!下面是spring boot
- 一、场景描述接《Java设计模式(一)工厂模式》工厂模式有一缺点,就是破坏了类的封闭性原则。例如,如果需要增加Word文件的数据采集,此时按
- 前言众所周知Java提供File类,让我们对文件进行操作,下面就来简单整理了一下File类的用法。 话不多说了,来一起看看详细的介绍吧1.基
- 本文为大家分享两个实例,相信大家一定会喜欢。实例1:随机生成验证码图片并将之输出为一个png文件效果图:import java.awt.Co
- 一:串口通信简介前段时间因为工作需要研究了一下android的串口通信,网上有很多讲串口通信的文章,我在做的时候也参考了很多文章,现在就将我
- 本文实例讲述了Android中资源文件用法。分享给大家供大家参考,具体如下:一、XML文件间资源文件的使用引用格式:attribute=&q
- MANIFEST.MF打开Java的JAR文件我们经常可以看到文件中包含着一个META-INF目录, 这个目录下会有一些文件,其中必有一个M
- 因为案例比较简单,所以简单用AndroidApplication -> Game -> Stage 搭建框架 一、主入口,无特殊
- 本文实例为大家分享了Android检测手机多点触摸点数的具体代码,供大家参考,具体内容如下说明:手指每点击一个地方,在那个地方就画一个圆第一
- 1. JWT的概念和特点JWT是一种轻量级、可扩展、可自包含的身份验证和授权机制。它是由三个部分组成:头部(Header)、载荷(Paylo
- Activity栈主要用于管理Activity的切换。当使用Intent跳转至某个目标Activity,需要根据目标Activity的加载模
- 前言最近在学习java8,所以接下来会给大家介绍一系列的Java8学习内容,那么让我们先从lambda表达式开始。众所周知从java8出现以
- 一、@RequestMapping注解的功能从注解名称上我们可以看到,@RequestMapping注解的作用就是将请求和处理请求的控制器方
- 一、材料准备1、jdk1.8的安装包2、maven安装包3、idea工具二、配置jdk1.8环境变量1.jdk下载jdk下载网址(点击此链接
- Java的集合类是一种特别有用的工具,它可以用于存储数量不等的多个对象,并可以实现常用的数据结构,如栈、队列等。Java集合还可以用于板寸具
- 本文汇总了几个WinForm中常见的实用技巧,对于C#程序开发有着很好的参考借鉴价值。具体分析如下:一、屏蔽窗体右上角关闭按钮1.重写OnC