一般关键词synchronized的用法
-
指定加锁对象:对给定对象加锁,进入同步代码前需要活的给定对象的锁。
-
直接作用于实例方法:相当于对当前实例加锁,进入同步代码前要获得当前实例的锁。
-
直接作用于静态方法:相当于对当前类加锁,进入同步代码前要获得当前类的锁。
可能存在的误区
-
由于对synchronized理解的不到位,由于很多时候,我们多线程都是操作一个synchronized的方法,当2个线程调用2个不同synchronized的方法的时候,认为是没有关系的,这种想法是存在误区的。直接作用于实例方法:相当于对当前实例加锁,进入同步代码前要获得当前实例的锁。
-
如果一个调用synchronized方法。另外一个调用普通方法是没有关系的,2个是不存在等待关系的。
方法1加了synchronized关键字,方法2没有加。如果线程1先执行方法一,线程2在执行方法2时。如果线程1没有执行完。那么线程2将会阻塞至线程1执行完后才执行。
代码如下:
package com.yulintu; /** * @author caomin * @date 2018/1/4 * @说明 */ public class CmThread implements Runnable{ private Integer a; public synchronized void method1() throws InterruptedException { System.out.println("进入方法一"); a=100; System.out.println("a="+a); method2(a); } public void method2(int a){ if (a!=0){ System.out.println(a); }else { a=200; System.out.println("b="+a); } } @Override public void run() { try { System.out.println("==="); method1(); } catch (InterruptedException e) { e.printStackTrace(); } } }
@Test public void test() throws InterruptedException { CmThread cmThread=new CmThread(); Thread thread=new Thread(cmThread); thread.start(); Thread.sleep(200); cmThread.method2(0); }
控制台输出如下:
Connected to the target VM, address: '127.0.0.1:53521', transport: 'socket'
===
进入方法一
a=100
100
Disconnected from the target VM, address: '127.0.0.1:53521', transport: 'socket'
b=200
Process finished with exit code 0