1 多线程问题,临界区
单线程由于按顺序继承(即使存在编译器优化,指令重排等优化策略也会保证程序的正确执行),多线程情况下,如果存在共享资源的情况,就会出现并发问题。
多个线程访问或者修改共享数据,会导致数据的不一致性,进而导致出错,线程同步机制就是用来防止错误发生的机制。
临界区定义为访问共享资源的代码块,如果同一时间能够保证只有一个线程访问临界区,就不会发生错误。
public class Demo6 {
public static void main(String[] args) {
int number = 10;
Thread thread1 = new Thread(new Thread1(number));
Thread thread2 = new Thread(new Thread1(number));
Thread thread3 = new Thread(new Thread2(number));
Thread thread4 = new Thread(new Thread2(number));
thread1.start();
thread2.start();
thread3.start();
thread4.start();
}
static class Thread1 implements Runnable{
private int number;
public Thread1(int number) {
super();
this.number = number;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
@Override
public void run() {
add();
}
private void add() {
while (number < 100) {
number += 1;
System.out.println("=====add=== "+number);
}
}
}
static class Thread2 implements Runnable{
private int number;
public Thread2(int number) {
super();
this.number = number;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
@Override
public void run() {
del();
}
private void del() {
while (number > 0) {
number -= 1;
System.out.println("=====del=== "+number);
}
}
}
}
2 同步
同步的含义是线程间协作,防止多线程访问共享资源的错误发生。
java实现同步的原理,当一个线程访问临界区时,判断是否有其他线程进入临界区,如果没有它才可以进入临界区,如果已经有线程进入临界区它会被同步挂起,直到进入的线程离开。
java提供了两种方式实现同步机制:
- synchronized
- Lock
两种方式都是利用锁的概念实现,所谓锁就需要一个唯一个标识,这里利用对象锁monitor(或者叫监视器)实现。
关于monitor的官方说明:
官方 说明:https://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html
同步建立在一个内部实体上叫做内部锁或者monitor 锁,(API规范通常是指该实体仅仅作为“监视器”),锁的作用:实施独占访问一个对象的状态并建立之前所必须的可见性的关系。
每一个对象都有一个内部锁与之关联。通常,一个线程访问之前需要获取该对象锁,然后任务完成时释放锁,一个线程在这期间独占锁。当多个线程都需要这个琐时,一个线程获取了对象锁,另一个线程将阻塞。
对象锁的理解:
在JVM的规范中,有这么一些话:
“在JVM中,每个对象和类在逻辑上都是和一个监视器相关联的”
“为了实现监视器的排他性监视能力,JVM为每一个对象和类都关联一个锁”
“锁住了一个对象,就是获得对象相关联的监视器”
Java中每个对象都有一个内置锁,当程序运行到非静态的synchronized同步方法上时,会自动获得与正在执行代码类的当前实例有关的锁。一个对象对应一个锁,线程获得该锁,其他线程无法再次获取这个锁,直到第一个线程释放锁,所以同一时间只能有一个线程进入synchronized方法或代码块。
参考:http://ifeve.com/monitors-java-synchronization-mechanism/