关键字的作用
摘自JDK 1.8
同步方法支持一种简单的策略来防止线程干扰h和内存一致性错误:如果一个对象对多个线程可见,则对该对象变量的所有读取或写入都是通过同步方法完成的。
通俗易懂的
能够保证在同一时刻最多只有一个线程在执行该段代码,以达到确保并发安全的效果。
地位
- 作为关键字,被Java语言原生支持
- 是最基本的同步手段
- 是并发编程的元老级角色,并发编程的必学内容
不使用并发的后果
一段非常简单的代码
public class DisappearRequest1 implements Runnable {
static DisappearRequest1 instance = new DisappearRequest1();
static int i = 0;
public static void main(String[] args) throws InterruptedException{
Thread t1 = new Thread(instance);
Thread t2 = new Thread(instance);
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(i);
}
@Override
public void run() {
for(int j=0; j<100000; j++) {
i++;
}
}
}
join()是Thread类的一个方法。根据jdk文档的定义:
public final void join()throws InterruptedException: Waits for this thread to die.
join()方法的作用,是等待这个线程结束;但显然,这样的定义并不清晰。
个人认为"Java 7 Concurrency Cookbook"的定义较为清晰:
join() method suspends the execution of the calling thread until the object called finishes its execution.
也就是说,t.join()方法阻塞调用此方法的线程(calling thread),直到线程t完成,此线程再继续;通常用于在main()主线程内,等待其它线程完成再结束main()主线程。
输出结果自然是远远小于200000,基本很少超过160000。原因就是i++这个动作在底层是分成3步来做的
- 从内存中读取i
- i++
- 写入内存
如果不控制并发,那么i的值就会被前一个被争夺走资源的线程在拿到CPU资源使把i“变小”(相当于后一个线程的对i加的循环没有作用了)
以上这种情况就是我们说的线程不安全