synchronized 关键字的使用场景
synchronized是典型的可冲入锁,jdk1.5之后做了较大的优化
如图,synchronized可以用在方法上也可以使用在代码块中,其中方法是实例方法和静态方法分别锁的是该类的实例对象和该类的对象。而使用在代码块中也可以分为三种,具体的可以看上面的表格。这里的需要注意的是:如果锁的是类对象的话,尽管new多个实例对象,但他们仍然是属于同一个类依然会被锁住,即线程之间保证同步关系。如果锁的是实例对象,则不同的线程会获取到不同的锁。
如果一个类被spring管理,且为单例的(默认单例);即使synchronized锁的是非静态方法,获取的是对象锁,但由于JVM中只存在一个对象,故作用和锁类对象类似,只允许一个线程进如该类;测试代码如下
@Component public class SynchronizedDemo { public synchronized void test1(){ System.out.println(Thread.currentThread().getName() + "进入方法1"); for(int i=0;i<10000000;i++){ } System.out.println(Thread.currentThread().getName() + "出去方法1"); } public synchronized void test2(){ System.out.println(Thread.currentThread().getName() + "进入方法2"); System.out.println(Thread.currentThread().getName() + "出去方法2"); } }
@RunWith(SpringRunner.class) @SpringBootTest public class AITest { @Autowired private SynchronizedDemo synchronizedDemo; CyclicBarrier cb = new CyclicBarrier(2); @Test public void testObjectLock() { new Thread(new Runnable() { @Override public void run() { try { cb.await(); } catch (InterruptedException | BrokenBarrierException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"->准备好了"); //synchronizedDemo.test1(); 1 SynchronizedDemo sd=new SynchronizedDemo(); sd.test1(); } }).start(); new Thread(new Runnable() { @Override public void run() { try { cb.await(); } catch (InterruptedException | BrokenBarrierException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"->准备好了"); //synchronizedDemo.test2(); 1 SynchronizedDemo sd=new SynchronizedDemo(); sd.test2(); } }).start(); } }