Synchronized can lock objects, code blocks, and class objects, so they use the difference, here we use the actual code to explore
package com.example.hxk.thread.synchroized;
public class SyncTest1 {
// synchronized modifies instance methods
public synchronized void test1(a) {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
try {
Thread.sleep(500);
} catch(InterruptedException e) { e.printStackTrace(); }}}// synchronized code block
public void test2(a) {
synchronized (this) {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
try {
Thread.sleep(500);
} catch(InterruptedException e) { e.printStackTrace(); }}}}public static void main(String[] args) {
SyncTest1 t1 = new SyncTest1();
new Thread(new Runnable() {
@Override
public void run(a) { t1.test1(); }},"thread1").start();
new Thread(new Runnable() {
@Override
public void run(a) { t1.test2(); }},"thread2").start(); }}Copy the code
Running results:
thread1 : 0
thread1 : 1
thread1 : 2
thread1 : 3
thread1 : 4
thread2 : 0
thread2 : 1
thread2 : 2
thread2 : 3
thread2 : 4
Copy the code
A synchronized code block locks the current object and the lock instance method. The synchronized code block locks the current object and the lock instance method.
Then we look at the class lock and modify the code as follows
package com.example.hxk.thread.synchroized;
public class SyncTest1 {
// Decorate static methods
public static synchronized void test1(a) {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
try {
Thread.sleep(500);
} catch(InterruptedException e) { e.printStackTrace(); }}}// Modify class objects
public void test2(a) {
synchronized (SyncTest1.class) {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
try {
Thread.sleep(500);
} catch(InterruptedException e) { e.printStackTrace(); }}}}public static void main(String[] args) {
SyncTest1 t1 = new SyncTest1();
new Thread(new Runnable() {
@Override
public void run(a) { SyncTest1.test1(); }},"thread1").start();
new Thread(new Runnable() {
@Override
public void run(a) { t1.test2(); }},"thread2").start(); }}Copy the code
Running results:
thread1 : 0
thread1 : 1
thread1 : 2
thread1 : 3
thread1 : 4
thread2 : 0
thread2 : 1
thread2 : 2
thread2 : 3
thread2 : 4
Copy the code
Synchronized modifys static methods and lock class objects in the same way that thread2 is blocked by Thread1. Let’s try using both class and object locks. The code is as follows
package com.example.hxk.thread.synchroized;
public class SyncTest1 {
// Decorate static methods
public static synchronized void test1(a) {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
try {
Thread.sleep(500);
} catch(InterruptedException e) { e.printStackTrace(); }}}// Modify class objects
public synchronized void test2(a) {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
try {
Thread.sleep(500);
} catch(InterruptedException e) { e.printStackTrace(); }}}public static void main(String[] args) {
SyncTest1 t1 = new SyncTest1();
new Thread(new Runnable() {
@Override
public void run(a) { SyncTest1.test1(); }},"thread1").start();
new Thread(new Runnable() {
@Override
public void run(a) { t1.test2(); }},"thread2").start(); }}Copy the code
Running results:
thread1 : 0
thread2 : 0
thread1 : 1
thread2 : 1
thread2 : 2
thread1 : 2
thread2 : 3
thread1 : 3
thread2 : 4
thread1 : 4
Copy the code
The result is alternate, indicating that the object lock and the class lock are not the same lock, they are two locks, do not affect each other
Conclusion: Synchronized modifications have the same effect on instance methods as synchronized(this){} blocks. Synchronized (synctest1.class) {} static methods are equivalent to synchronized (synctest1.class) {} blocks. Modifying static methods to represent locks is class objects (a class has only one class object in the JVM)