在java并发编程中,会遇到三个问题:

  • 原子性
  • 有序性
  • 可见性

一、原子性

1)概念
原子性:即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。
2)实例
对于操作:

++i

将它反编译成汇编代码:

mov ecx ,dword ptr [ebp - 4]  ;把变量i的值送 ecx 
add ecx,1 
mov dword ptr [ebp - 4],ecx  ;ecx加1后,赋值给i

在反编译成汇编可以看出顺序是先将i本身的值拿到寄存器ecx中,然会对寄存器自增,最后写回值。
借助java我可以通过看出如果内部不加阻塞,最后读出的结果是脏的。

/**
 * 不共享数据count,每个线程自己维护自己的count
 * @author 我们
 *
 */
public class T1 extends Thread {
	private int count = 0;
	public T1(String name) {
		super();
		this.setName(name);
	}

	public void run() {
		super.run();
		while (count < 5) {
			++count;
			System.out.println("由" + this.currentThread().getName()
					+ "计算.count=" + count);
		}
	}

	public static void main(String[] args) {
		T1 aMythread = new T1("A");
		T1 bMythread = new T1("B");
		T1 cMythread = new T1("C");
		aMythread.start();
		bMythread.start();
		cMythread.start();
	}
}
/*----output--------
由B计算.count=1
由A计算.count=1
由C计算.count=1
由C计算.count=2
由C计算.count=3
由C计算.count=4
由A计算.count=2
由B计算.count=2
由B计算.count=3
由B计算.count=4
由A计算.count=3
由C计算.count=5
由A计算.count=4
由A计算.count=5
由B计算.count=5
*/

如果我们想要它正常的执行,只需要在run前面加synchronized

二、有序性

1)概念
有序性:即程序执行的顺序按照代码的先后顺序执行。
2)实例
在开发并发程序的时候如果控制不好,程序的执行可能出现乱序的结果。

class OrderExample {
	public int a = 0;
	public boolean flag = false;

	public void write() throws InterruptedException {
		a = 1;![在这里插入图片描述](https://img-blog.csdnimg.cn/20191104144341904.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zOTQ0MzQ4Mw==,size_16,color_FFFFFF,t_70)
		flag = true;
		System.out.println("---write()---" + Thread.currentThread().getName());
	}
	public void reader() {
		if (flag) {
			int i = a + 1;
			System.out.println("---reader()---i=" + i + "  " + Thread.currentThread().getName());
		}
	}
}
class t1 extends Thread {
	private OrderExample orderExample;
	public t1(OrderExample orderExample) {
		super();
		this.orderExample = orderExample;
	}
	public void run() {
		try {
			orderExample.write();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
class t2 extends Thread {
	private OrderExample orderExample;
	public t2(OrderExample orderExample) {
		super();
		this.orderExample = orderExample;
	}
	public void run() {
		orderExample.reader();
	}
}
public class Test4 {
	public static void main(String[] args) throws InterruptedException {
		OrderExample orderExample = new OrderExample();
		t1 myT1 = new t1(orderExample);
		t2 myT2 = new t2(orderExample);
		
		myT1.start();
		myT2.start();
	}
}
/*------output-----
---write()---Thread-0
*/

程序的执行顺序可能未必和书写的顺序一致(可能对于现在的处理器该结果比较难模拟)

java 并发 传参_System

三、可见性

1)概念

可见性是指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。

2)实例

java 并发 传参_System_02

四、线程安全

1)概念
指某个函数、函数库在多线程环境中被调用时,能够正确地处理各个线程的局部变量,使程序功
能正确完成。
在java中采用阻塞的方式比较常见(synchronized),同时也可以采用关键字volatile来使变量在多个线程间可见。