一、java多线程产生的问题:

Java允许多线程并发控制,当多个线程同时操作一个可共享的资源变量时(如数据的增删改查),将会导致数据不准确,相互之间产生冲突。

因此加入同步锁以避免在该线程没有完成操作之前,被其他线程的调用,从而保证了该变量的唯一性和准确性。两种锁分别是:synchronized和ReentrantLock

二、synchronized关键字

Synchronzied实现同步的表现形式分为:代码块同步和方法同步。

1、非static方法同步

public synchronized void method1(){}

锁住的是该对象,类的其中一个实例,当该对象(仅仅是这一个对象)在不同线程中执行这个同步方法时,线程之间会形成互斥,达到同步效果。
但如果不同线程同时对该类的不同对象执行这个同步方法时,则线程之间不会形成互斥,因为他们拥有的是不同的锁。

2、代码块同步

synchronized(this){ //TODO }

描述同1

3、static方法同步

锁住的是该类,当所有该类的对象(多个对象)在不同线程中调用这个static同步方法时,线程之间会形成互斥,达到同步效果。

4、代码块同步

synchronized(Test.class){ //TODO}

描述同3

5、总结:

<1> 当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。

<2> 当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。

<3> 尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。

<4> 当两个并发线程访问synchronized修饰不同或相同静态方法时,那么一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完后才能执行。

<5> 当一个线程访问一个synchronized修饰静态方法,另一个访问synchronized修饰非静态方法时,那么不同的线程依然可以同时访问,这是因为类锁和对象锁是两个不一样的锁,控制着不同的区域,它们是互不干扰的

<6> 当一个线程访问一个synchronized修饰静态方法,另一个访问非synchronized修饰的方法时,那么不同的线程依然可以同时访问。