/**
* synchronized(this) 只能锁当前对象
* synchronized(A.class) 锁类,对类的所有实例生效
*/
public class Synchronized {
public void method1() { // 锁当前对象
try {
synchronized (this) {
System.out.println("this method1 start time=" + System.currentTimeMillis());
Thread.sleep(2000);
System.out.println("this method1 end time=" + System.currentTimeMillis());
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
public synchronized void method2() { // 与method1存在竞争关系
System.out.println(" method2 start time=" + System.currentTimeMillis());
System.out.println(" method2 end time=" + System.currentTimeMillis());
}
public void method3() { // 锁类,对类的所有实例生效
synchronized (Synchronized.class) {
try {
System.out.println("class method3 start time=" + System.currentTimeMillis());
Thread.sleep(4000);
System.out.println("class method3 end time=" + System.currentTimeMillis());
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
public static synchronized void method4() { // 与method3存在竞争关系
System.out.println("static method4 start time=" + System.currentTimeMillis());
System.out.println("static method4 end time=" + System.currentTimeMillis());
}
}
class Thread1 extends Thread {
private Synchronized objectService;
public Thread1(Synchronized objectService) {
super();
this.objectService = objectService;
}
@Override
public void run() {
super.run();
objectService.method1();
}
}
class Thread2 extends Thread {
private Synchronized objectService;
public Thread2(Synchronized objectService) {
super();
this.objectService = objectService;
}
@Override
public void run() {
super.run();
objectService.method2();
}
}
class Thread3 extends Thread {
private Synchronized objectService;
public Thread3(Synchronized objectService) {
super();
this.objectService = objectService;
}
@Override
public void run() {
super.run();
objectService.method3();
}
}
class Thread4 extends Thread {
private Synchronized objectService;
public Thread4(Synchronized objectService) {
super();
this.objectService = objectService;
}
@Override
public void run() {
super.run();
objectService.method4();
}
}
class MainTest {
public static void main(String[] args) {
Synchronized service = new Synchronized();
new Thread1(service).start();
new Thread2(service).start();
new Thread3(service).start();
new Thread4(service).start();
}
}
输出结果:
从时间线可以看出method1
和method2
、method3
和method4
存在竞争关系。
当一个线程访问Synchronized类的一个synchronized (this)同步代码块时,其它线程对同一个Synchronized类中其它的synchronized ()同步方法的访问将是堵塞;访问synchronized (Synchronized.class)同步代码块时, static synchronized同步方法的访问将是阻塞,这说明synchronized (this)和synchronized ()同步方法、synchronized (Synchronized.class)同步代码块和 static synchronized同步方法使用的对象监视器是一个。
synchronized同步方法和synchronized(this)同步代码块
/**
* synchronized(this)锁定当前对象
*/
public class SynchronizedThis {
public void methodA() {
try {
synchronized (this) {
System.out.println("this methodA 线程名称:" + Thread.currentThread().getName() + " begin time=" + System.currentTimeMillis());
for (int i = 1; i <= 2; i++) {
System.out.println("this methodA 线程名称:" + Thread.currentThread().getName() + "-->i=" + i);
Thread.sleep(100);
}
System.out.println("this methodA 线程名称:" + Thread.currentThread().getName() + " end time=" + System.currentTimeMillis());
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void methodB() {
synchronized (this) {
try {
System.out.println("this methodB 线程名称:" + Thread.currentThread().getName() + " begin time=" + System.currentTimeMillis());
for (int i = 1; i <= 2; i++) {
System.out.println("this methodB 线程名称:" + Thread.currentThread().getName() + "-->i=" + i);
Thread.sleep(100);
}
System.out.println("this methodB 线程名称:" + Thread.currentThread().getName() + " end time=" + System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public synchronized void methodC() {
try {
System.out.println(" methodC 线程名称:" + Thread.currentThread().getName() + " begin time=" + System.currentTimeMillis());
for (int i = 1; i <= 2; i++) {
System.out.println(" methodC 线程名称:" + Thread.currentThread().getName() + "-->i=" + i);
Thread.sleep(100);
}
System.out.println(" methodC 线程名称:" + Thread.currentThread().getName() + " end time=" + System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class ThisThreadA extends Thread {
private SynchronizedThis synchronizedThis;
public ThisThreadA(SynchronizedThis synchronizedThis) {
super();
this.synchronizedThis = synchronizedThis;
}
@Override
public void run() {
super.run();
synchronizedThis.methodA();
}
}
class ThisThreadB extends Thread {
private SynchronizedThis synchronizedThis;
public ThisThreadB(SynchronizedThis synchronizedThis) {
super();
this.synchronizedThis = synchronizedThis;
}
@Override
public void run() {
super.run();
synchronizedThis.methodB();
}
}
class ThisThreadC extends Thread {
private SynchronizedThis synchronizedThis;
public ThisThreadC(SynchronizedThis synchronizedThis) {
super();
this.synchronizedThis = synchronizedThis;
}
@Override
public void run() {
super.run();
synchronizedThis.methodC();
}
}
class ThisMainTest {
public static void main(String[] args) {
SynchronizedThis service = new SynchronizedThis();
ThisThreadA a = new ThisThreadA(service);
a.setName("ThreadA");
a.start();
ThisThreadB b = new ThisThreadB(service);
b.setName("ThreadB");
b.start();
ThisThreadC c = new ThisThreadC(service);
c.setName("ThreadC");
c.start();
}
}
输出结果
多个线程调用同一个对象中的不同名称的synchronized同步方法或synchronized(this)同步代码块时,是同步的。
synchronized同步方法和synchronized(this)同步代码块是相互竞争关系
- 对其它的synchronized同步方法或synchronized(this)同步代码块调用是堵塞状态;
- 同一时间只有一个线程执行synchronized同步方法或synchronized(this)同步代码块中的代码。
静态同步synchronized方法
/**
* 静态同步synchronized方法
* synchronized应用在static方法上,那是对当前对应的*.Class进行持锁。
*/
public class SynchronizedStatic {
public synchronized static void methodA() {
try {
System.out.println("static methodA 线程名称:" + Thread.currentThread().getName() + " begin times:" + System.currentTimeMillis());
for (int i = 1; i <= 5; i++) {
System.out.println("static methodA 线程名称:" + Thread.currentThread().getName() + "-->i=" + i);
Thread.sleep(1000);
}
System.out.println("static methodA 线程名称:" + Thread.currentThread().getName() + " end times:" + System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized static void methodB() {
System.out.println("static methodB 线程名称:" + Thread.currentThread().getName() + " begin times:" + System.currentTimeMillis());
System.out.println("static methodB 线程名称:" + Thread.currentThread().getName() + " end times:" + System.currentTimeMillis());
}
}
class StaticThreadA extends Thread {
@Override
public void run() {
SynchronizedStatic.methodA();
}
}
class StaticThreadB extends Thread {
@Override
public void run() {
SynchronizedStatic.methodB();
}
}
class StaticMainTest {
public static void main(String[] args) {
StaticThreadA a = new StaticThreadA();
a.setName("ThreadA");
a.start();
StaticThreadB b = new StaticThreadB();
b.setName("ThreadB");
b.start();
}
}
输出结果
synchronized应用在static方法上,那是对当前对应的*.Class进行持锁,与同步synchronized(*.class)代码块作用一样。
对比下面代码进行验证
synchronized(*.class)代码块
/**
* synchronized(*.class)代码块
* 同步synchronized(*.class)代码块的作用其实和synchronized static方法作用一样。
* Class锁对类的所有对象实例起作用。
*/
public class SynchronizedClass {
public void methodA() {
try {
synchronized (SynchronizedClass.class) {
System.out.println("class methodA 线程名称:" + Thread.currentThread().getName() + " begin times:" + System.currentTimeMillis());
for (int i = 1; i <= 5; i++) {
System.out.println("class methodA 线程名称:" + Thread.currentThread().getName() + "-->i=" + i);
Thread.sleep(1000);
}
System.out.println("class methodA 线程名称:" + Thread.currentThread().getName() + " end times:" + System.currentTimeMillis());
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void methodB() {
synchronized (SynchronizedClass.class) {
System.out.println("class methodB 线程名称:" + Thread.currentThread().getName() + " begin times:" + System.currentTimeMillis());
System.out.println("class methodB 线程名称:" + Thread.currentThread().getName() + " end times:" + System.currentTimeMillis());
}
}
}
class ClassThreadA extends Thread {
private SynchronizedClass objectService;
public ClassThreadA(SynchronizedClass objectService) {
super();
this.objectService = objectService;
}
@Override
public void run() {
objectService.methodA();
}
}
class ClassThreadB extends Thread {
private SynchronizedClass objectService;
public ClassThreadB(SynchronizedClass objectService) {
super();
this.objectService = objectService;
}
@Override
public void run() {
objectService.methodB();
}
}
class ClassMainTest {
public static void main(String[] args) {
SynchronizedClass service = new SynchronizedClass();
ClassThreadA a = new ClassThreadA(service);
a.setName("ThreadA");
a.start();
ClassThreadB b = new ClassThreadB(service);
b.setName("ThreadB");
b.start();
}
}
// Class锁对类的所有对象实例起作用。
class ClassMainTest2 {
public static void main(String[] args) {
SynchronizedClass service1 = new SynchronizedClass();
SynchronizedClass service2 = new SynchronizedClass();
ClassThreadA a = new ClassThreadA(service1);
a.setName("ThreadA-service1");
a.start();
ClassThreadB b = new ClassThreadB(service2);
b.setName("ThreadB-service2");
b.start();
}
}
输出结果
同步synchronized(*.class)
代码块的作用其实和synchronized static
方法作用一样。
Class锁对类的所有对象实例起作用。