Synchronized常用三种使用方式
1、修饰普通方法:锁对象即为当前对象
2、修饰代码块:锁对象为synchronized紧接着的小括号内的对象
3、修饰静态方法:锁对象为当前Class对象
1、修饰普通方法
public class MyThread extends Thread{
private int count=5;
@SneakyThrows
@Override
public void run() {
doSomething();
}
public synchronized void doSomething(){
String name = Thread.currentThread().getName();
System.out.println(name+"开始执行任务");
try {
count--;
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name+"任务结束,count="+count);
}
public static void main(String[] args) {
MyThread myThread=new MyThread();
Thread threadA = new Thread(myThread,"线程A");
Thread threadB = new Thread(myThread,"线程B");
Thread threadC = new Thread(myThread,"线程C");
Thread threadD = new Thread(myThread,"线程D");
Thread threadE = new Thread(myThread,"线程E");
threadA.start();
threadB.start();
threadC.start();
threadD.start();
threadE.start();
while (threadA.isAlive()|| threadB.isAlive()|| threadC.isAlive()
|| threadD.isAlive()|| threadE.isAlive()){
}
System.out.println("main finish");
}
}
结果:
2、修饰代码块:锁对象为synchronized紧接着的小括号内的对象
public class MyThread extends Thread{
private int count=5;
@SneakyThrows
@Override
public void run() {
synchronized (this){
String name = Thread.currentThread().getName();
System.out.println(name+"开始执行任务");
try {
count--;
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name+"任务结束,count="+count);
}
}
public static void main(String[] args) {
MyThread myThread=new MyThread();
Thread threadA = new Thread(myThread,"线程A");
Thread threadB = new Thread(myThread,"线程B");
Thread threadC = new Thread(myThread,"线程C");
Thread threadD = new Thread(myThread,"线程D");
Thread threadE = new Thread(myThread,"线程E");
threadA.start();
threadB.start();
threadC.start();
threadD.start();
threadE.start();
while (threadA.isAlive()|| threadB.isAlive()|| threadC.isAlive()
|| threadD.isAlive()|| threadE.isAlive()){
}
System.out.println("main finish");
}
}
3、修饰静态方法:锁对象为当前Class对象
因为 static 方法在类加载的时候就加载了,所以这个锁应该是类的字节码对象。
synchronized 关键字修饰 static 方法的时候,同步锁是该类的字节码对象,即等效于代码块 synchronized(classname.class){...}。
public class MyThread extends Thread{
private static int count=5;
@SneakyThrows
@Override
public void run() {
doSomething();
}
public synchronized static void doSomething(){
String name = Thread.currentThread().getName();
System.out.println(name+"开始执行任务");
try {
count--;
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name+"任务结束,count="+count);
}
public static void main(String[] args) {
MyThread myThread=new MyThread();
Thread threadA = new Thread(myThread,"线程A");
Thread threadB = new Thread(myThread,"线程B");
Thread threadC = new Thread(myThread,"线程C");
Thread threadD = new Thread(myThread,"线程D");
Thread threadE = new Thread(myThread,"线程E");
threadA.start();
threadB.start();
threadC.start();
threadD.start();
threadE.start();
while (threadA.isAlive()|| threadB.isAlive()|| threadC.isAlive()
|| threadD.isAlive()|| threadE.isAlive()){
}
System.out.println("main finish");
}
}
结果: