几个并发编程的例子
在这里讨论一下自己遇到的几个自己感觉比较好的并发编程的例子。如果读者已经完全明白是怎么回事,请略过。
例一:
先看如下程序,想一下这个程序多长时间结束?
- import java.util.concurrent.TimeUnit;
- public class Stop {
- private static boolean isStop = false;
- public static void main(String[] args) throws Exception {
- Thread thread = new Thread(new Runnable(){
- public void run(){
- int count = 0;
- while(!isStop){
- count++;
- }
- System.out.println("循环结束,此时count值为:" + count);
- }
- });
- thread.start();
- TimeUnit.SECONDS.sleep(1);
- isStop = true;
- }
- }
在我的机器上,这个程序永远停不下来!你也可以在自己的机器上试一下。
这是为什么呢?
原因是:虽然在主线程中修改了isStop的值,但是在线程thread中永远看不到修改后的值,虽然循环在执行,在进行检测。在《Effective Java》中我们可以看到这样的解释,由于没有同步,虚拟机将这个代码:
- while(!isStop){
- count++;
- }
转变成了这样:
- if(!isStop){
- while(true){
- count++;
- }
- }
修正这个问题的一种方式是,同步访问isStop这个域,这样程序才会如期停止。在上面的程序中添加如下代码片段即可:
- private static synchronized void stop(){
- isStop = true;
- }
- private static synchronized boolean stoped(){
- return isStop;
- }
其实在上面我们可以看到,上面的方法即使没有被同步也是原子的,但是这里为什么要这么做呢,原因只是为了synchronized的通信效果,而不是互斥访问。
还一种修改方式更为简洁,只需要将isStop声明为volatile即可,这样上面的同步方法即可略去,volatile可以保证任何一个线程在读取该域的时候都将看到最近被写入的值。
例二:
上面提到了volatile,我们可以再看一个使用它的例子,如下:
- private static volatile int number = 0;
- public static int nextNumber(){
- return number++;
- }
上面这个方法的目的是让每个调用都返回不同的值,但是不要超过int的范围。但是上面的这个方法是无法正常工作的,问题出现在哪呢?问题出现在递增操作符(++)不是原子的。这个操作在number域中执行两项操作,首先读取值,然后再写入新的值。如果一个线程在另一个线程读取旧值和写回新值的这个期间读取这个域,那么两个线程看到的是同一个值,所以会返回相同的值。
对于这个我们的修改方式就是使用synchronized关键字,这样可以保证不会出现交叉调用的出现,或是使用java.util.concurrent.atomic的一部分来达到效果。
例三:
下面再看这样一个程序,它最后会保证a,b两个数字相同吗?
- import java.io.IOException;
- public class MThread{
- public static void main(String[] args) throws IOException{
- ShareObject so = new ShareObject();
- Thread thread1 = new Thread(new ThreadOperation(so,"add"));
- Thread thread2 = new Thread(new ThreadOperation(so,"sub"));
- thread1.setDaemon(true);
- thread2.setDaemon(true);
- thread1.start();
- thread2.start();
- System.out.println("按Enter键结束!");
- System.in.read();
- System.out.println("此时的so里面的a,b分别为a="+so.a+"b="+so.b);
- }
- }
- class ThreadOperation implements Runnable{
- private String operation;
- private ShareObject so;
- public ThreadOperation(ShareObject so,String oper){
- this.operation = oper;
- this.so = so;
- }
- public void run() {
- while(true){
- if(operation.equals("add")){
- so.add();
- }else{
- so.sub();
- }
- }
- }
- }
- class ShareObject{
- int a = 100;
- int b = 100;
- public synchronized void add(){
- ++a;
- ++b;
- }
- public synchronized void sub(){
- --a;
- --b;
- }
- }
经过我自己的运行,运行出来的a,b的值相差很大,如下所示:
此时的so里面的a,b分别为 a=4553016b=4552099
这是为什么呢?我再来一个更迷惑的解决方法,我们可以试着给run()方法里面执行完加或者减操作后添加一个停止很短时间的代码,结果输出就会正确!添加后如下:
- public void run() {
- while(true){
- if(operation.equals("add")){
- so.add();
- }else{
- so.sub();
- }
- try {
- TimeUnit.MILLISECONDS.sleep(1);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
相关推荐
│ 高并发编程第二阶段05讲、一个解释volatile关键字作用最好的例子.mp4 │ 高并发编程第二阶段06讲、Java内存模型以及CPU缓存不一致问题的引入.mp4 │ 高并发编程第二阶段07讲、CPU以及CPU缓存的结构,解决高速...
│ 高并发编程第二阶段05讲、一个解释volatile关键字作用最好的例子.mp4 │ 高并发编程第二阶段06讲、Java内存模型以及CPU缓存不一致问题的引入.mp4 │ 高并发编程第二阶段07讲、CPU以及CPU缓存的结构,解决高速...
本书主要涵盖以下几个关键知识点: 1. **线程基础**:首先,你需要了解线程的基本概念,包括如何创建和管理线程。在Java中,可以通过实现`Runnable`接口或继承`Thread`类来创建线程。同时,Java还提供了`...
在Java 7中,并发编程得到了显著的提升,主要体现在以下几个方面: 1. **Fork/Join框架**:Java 7引入了Fork/Join框架,这是一个用于并行执行任务的高级框架,基于工作窃取算法。它将大任务拆分为小任务,并在多个...
在Java并发编程中,主要涉及以下几个关键知识点: 1. **线程与进程**:首先,理解线程和进程的基本概念是至关重要的。线程是程序执行的最小单位,而进程则是资源分配的基本单位。Java通过Thread类和Runnable接口来...
在并发编程中,有几个关键问题值得深入探讨。首先,我们来看一下这些具体的问题: 1. **工作线程数设置**:并非工作线程数设置得越大越好。理想情况下,线程数应该根据系统的硬件资源(如CPU核心数)以及任务特性来...
本文将对以下几个知识点进行详细阐述: 1. 网络编程基本概念 网络编程涉及不同计算机或网络设备间通过网络进行数据交换的过程。在这个过程中,网络通信模型的设计至关重要,因为不同的模型会影响服务的并发性能和...
并发编程中的同步模式之一是保护性暂停模式,该模式用于确保一个线程在等待另一个线程完成某项任务后才能继续执行。这种模式下的线程关联同一个GuardedObject,它能够保护线程间的同步,并且能够处理线程间的通信。 ...
### Go 并发编程知识点详解 #### 一、并发编程概览 在现代软件开发中,**并发编程**已经成为了一项必备技能。特别是在高负载、高性能的应用场景下,利用好并发能够极大地提升程序的执行效率和响应速度。Golang...
在Java并发编程中,有几个核心的知识点是必须要掌握的: 1. **线程**:Java通过`Thread`类来创建和管理线程,它是并发的基础。线程允许程序在同一时刻执行多个任务,提高系统资源利用率。 2. **同步机制**:为了...
本书的核心内容涵盖了以下几个方面: 1. **线程基础**:讲解了Java中的Thread类和Runnable接口,以及如何创建和启动线程。此外,还介绍了线程的生命周期和状态,包括新建、就绪、运行、阻塞和终止等。 2. **同步...
在这个源码库中,你可以找到以下几个重要的并发编程知识点: 1. **线程安全**:书中的例子会涵盖各种线程安全的实现方式,如synchronized关键字、volatile变量、Atomic类等。理解这些机制能帮助你确保多线程环境下...
`Semaphore`类主要包含以下几个方法: 1. `acquire()`: 这个方法用于获取一个许可。如果没有可用的许可,线程会被阻塞直到有一个许可被释放。 2. `tryAcquire()`: 尝试获取一个许可,但不会阻塞。如果当前没有可用的...
总之,“C#高效率SOCKET并发端口例子”是一个实践性强、涉及面广的学习资料,涵盖了网络编程中的基础概念和高级技巧,对于提升C#网络编程能力大有裨益。通过学习和理解这个示例,开发者可以更好地应对各种网络应用...
总的来说,这个例子涵盖了以下几个关键知识点: 1. Django项目的创建和结构。 2. Django中的视图、模型和URL配置。 3. Python线程和并发处理。 4. Linux环境下的并发支持。 5. 处理临界资源的锁机制。 6. Django的...
CyclicBarrier的主要方法有以下几个: 1. `CyclicBarrier(int parties)`: 构造一个CyclicBarrier,参数parties指定了需要等待的线程数量。当所有线程都到达屏障点时,屏障才会放行。 2. `void await() throws ...
写在前面 并发编程一直都存在,只不过过去的很长时间里,比较...关于并发编程的几个误解 误解一:并发编程就是多线程 实际上多线只是并发编程的一中形式,在C#中还有很多更实用、更方便的并发编程技术,包括异步编
7. **多线程应用**:在服务器端,为了处理多个并发连接,通常需要使用多线程。MFC提供了CWinThread类,可以创建并管理线程,确保每个连接都有独立的工作线程处理。 8. **关闭连接**:完成通信后,记得调用Close()...
并发编程 这个系列,我准备了将近一个星期,从知识点梳理,到思考要举哪些例子才能更加让人容易吃透这些知识点。希望呈现出来的效果真能如想象中的那样,对小白也一样的友好。 昨天大致整理了下,这个系列我大概会...