keyword synchronized It can also be applied to static Statically , If you write like this , That's right now .java File corresponding Class Class to lock .*
Here is an example to illustrate the usage and effect .
(1) Service.java
public class Service {
synchronized public static void printA() {
try {
System.out.println(" The thread name is :" + Thread.currentThread().getName()
+ " stay " + System.currentTimeMillis() + " Get into printA");
Thread.sleep(3000);
System.out.println("-- The thread name is :" + Thread.currentThread().getName()
+ " stay " + System.currentTimeMillis() + " Leave printA");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized public static void printB() {
System.out.println(" The thread name is :" + Thread.currentThread().getName() + " stay "
+ System.currentTimeMillis() + " Get into printB");
System.out.println(" The thread name is :" + Thread.currentThread().getName() + " stay "
+ System.currentTimeMillis() + " Leave printB");
}
}
(2) ThreadA.java
public class ThreadA extends Thread {
@Override
public void run() {
Service.printA();
}
}
(3) ThreadB.java
public class ThreadB extends Thread {
@Override
public void run() {
Service.printB();
}
}
(4) Run.java
public class Run {
public static void main(String[] args) {
ThreadA a = new ThreadA();
a.setName("A");
a.start();
ThreadB b = new ThreadB();
b.setName("B");
b.start();
}
}
The thread name is :A stay 1634056855437 Get into printA
-- The thread name is :A stay 1634056858458 Leave printA
The thread name is :B stay 1634056858458 Get into printB
The thread name is :B stay 1634056858459 Leave printB
From the results of operation , Nothing special , It's all synchronous , And will be synchronized Keywords added to non static The effect of the method is the same . In fact, there are essential differences ,synchronized Keywords added to static Static method is to give Class Class lock , and synchronized Keywords added to non static Static methods are object locking .
To prove that it's not the same lock , We can verify it through the following experiments :
(1) Service.java
public class Service {
synchronized public static void printA() {
try {
System.out.println(" The thread name is :" + Thread.currentThread().getName()
+ " stay " + System.currentTimeMillis() + " Get into printA");
Thread.sleep(3000);
System.out.println("---- The thread name is :" + Thread.currentThread().getName()
+ " stay " + System.currentTimeMillis() + " Leave printA");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized public static void printB() {
System.out.println(" The thread name is :" + Thread.currentThread().getName() + " stay "
+ System.currentTimeMillis() + " Get into printB");
System.out.println(" The thread name is :" + Thread.currentThread().getName() + " stay "
+ System.currentTimeMillis() + " Leave printB");
}
synchronized public void printC() {
System.out.println(" The thread name is :" + Thread.currentThread().getName() + " stay "
+ System.currentTimeMillis() + " Get into printC");
System.out.println("???? The thread name is :" + Thread.currentThread().getName() + " stay "
+ System.currentTimeMillis() + " Leave printC");
}
}
(2) ThreadA.java
public class ThreadA extends Thread {
private Service service;
public ThreadA(Service service) {
super();
this.service = service;
}
@Override
public void run() {
service.printA();
}
}
(3) ThreadB.java
public class ThreadB extends Thread {
private Service service;
public ThreadB(Service service) {
super();
this.service = service;
}
@Override
public void run() {
service.printB();
}
}
(4) ThreadC.java
public class ThreadC extends Thread {
private Service service;
public ThreadC(Service service) {
super();
this.service = service;
}
@Override
public void run() {
service.printC();
}
}
(5) Run.java
public class Run {
public static void main(String[] args) {
Service service = new Service();
ThreadA a = new ThreadA(service);
a.setName("A");
a.start();
ThreadB b = new ThreadB(service);
b.setName("B");
b.start();
ThreadC c = new ThreadC(service);
c.setName("C");
c.start();
}
}
Execution results :
The thread name is :A stay 1634056663156 Get into printA
The thread name is :C stay 1634056663157 Get into printC
???? The thread name is :C stay 1634056663185 Leave printC
---- The thread name is :A stay 1634056666186 Leave printA
The thread name is :B stay 1634056666186 Get into printB
The thread name is :B stay 1634056666186 Leave printB
The experimental results show that : This experiment actually sets up two locks :
- Object lock :printC Yes no static method , Constrained by object locks
- Class lock :PrintA、PrintB It's a static method , All by the same Class constraint
The above can also be Service.java In code PrintB Change it to :
synchronized public void printB() {
System.out.println(" The thread name is :" + Thread.currentThread().getName() + " stay "
+ System.currentTimeMillis() + " Get into printB");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(" The thread name is :" + Thread.currentThread().getName() + " stay "
+ System.currentTimeMillis() + " Leave printB");
}
Rerun , give the result as follows :
The thread name is :B stay 1634058460652 Get into printB
The thread name is :A stay 1634058460652 Get into printA
---- The thread name is :A stay 1634058461681 Leave printA
The thread name is :B stay 1634058465681 Leave printB
The thread name is :C stay 1634058465681 Get into printC
???? The thread name is :C stay 1634058465682 Leave printC
PrintB and PrintC Are non static , Belong to the same lock , therefore C Waiting B Release the lock when finished .
The reason for asynchrony is to hold different locks , One is object lock , The other is Class lock , and Class Locks work on all object instances of the class .
Sync synchronized(class) The function of code block is actually the same as synchronized static The method works the same .
With the following example ( Omit Thread file ) Verify that :
(1) Service.java
public class Service {
public static void printA() {
synchronized (Service.class) {
try {
System.out.println(" The thread name is :" + Thread.currentThread().getName()
+ " stay " + System.currentTimeMillis() + " Get into printA");
Thread.sleep(3000);
System.out.println("---- The thread name is :" + Thread.currentThread().getName()
+ " stay " + System.currentTimeMillis() + " Leave printA");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void printB() {
synchronized (Service.class) {
System.out.println(" The thread name is :" + Thread.currentThread().getName()
+ " stay " + System.currentTimeMillis() + " Get into printB");
System.out.println("++++ The thread name is :" + Thread.currentThread().getName()
+ " stay " + System.currentTimeMillis() + " Leave printB");
}
}
}
(2)Run.java
public class Run {
public static void main(String[] args) {
Service service1 = new Service();
Service service2 = new Service();
ThreadA a = new ThreadA(service1);
a.setName("A");
a.start();
ThreadB b = new ThreadB(service2);
b.setName("B");
b.start();
}
}
Execution results :
The thread name is :A stay 1634098725887 Get into printA
---- The thread name is :A stay 1634098728911 Leave printA
The thread name is :B stay 1634098728911 Get into printB
++++ The thread name is :B stay 1634098728912 Leave printB