synchronized:意思是 同步,也就是 共享资源
Synchronized修饰方法:对象锁
Static Synchronized修饰方法:类锁
下面代码手动敲一遍,就会理解
一、Synchronized修饰方法
1、一个对象,启动多个线程,竞争一把对象锁
package sync;
/*
* 一个对象,启动多个线程,竞争一把对象锁
*/
public class MyThread extends Thread{
private int count = 5;
public synchronized void run() {
count--;
System.out.println(this.currentThread().getName() + " count = " + count);
}
public static void main(String[] args) {
//新建一个对象
MyThread myThread = new MyThread();
//启动多个线程
Thread t1 = new Thread(myThread,"t1");
Thread t2 = new Thread(myThread,"t2");
Thread t3 = new Thread(myThread,"t3");
Thread t4 = new Thread(myThread,"t4");
Thread t5 = new Thread(myThread,"t5");
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
}
}
输出结果:
t1 count = 4
t4 count = 3
t5 count = 2
t3 count = 1
t2 count = 0
这五个线程,哪个先执行,哪个后执行,要看CPU调度
2、多个对象,启动多个线程,竞争多把对象锁
package sync;
public class MultiThread {
private int num = 0;
public synchronized void printNum(String tag) {
try {
if(tag.equals("a")) {
num = 100;
System.out.println("tag a , set num over!");
Thread.sleep(1000);
System.out.println("tag " + tag + ", num = " + num);
}else {
num = 200;
System.out.println("tag b , set num over!");
Thread.sleep(1000);
System.out.println("tag " + tag + ", num = " + num);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
//新建两个对象m1 、m2
MultiThread m1 = new MultiThread();
MultiThread m2 = new MultiThread();
//新建第一个线程,调用m1对象的printNum()方法
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
m1.printNum("a");
}
});
//新建第二个线程,调用m2对象的printNum()方法
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
m2.printNum("b");
}
});
//同时启动两个线程
t1.start();
t2.start();
//是先执行完线程t1,再执行线程t2吗?
}
}
输出结果:
tag b , set num over!
tag a , set num over!
tag b, num = 200
tag a, num = 100
可以看到,线程t1和线程t2是同时执行,两个线程互不影响,独立执行,因此输出结果自然不分先后.
第一个对象m1访问后,锁住m1这个对象;然后,第二个对象m2继续访问,不会被m1锁影响到。
结论:
(1)synchronized是对象锁,多个对象多个锁,锁的是对象。
(2)而不是把一个方法或者一个类当作锁(一个Class类可以new多个对象嘛)
二、Static Synchronized修饰方法
在静态方法上加上synchronized关键字,表示锁定class类,类一级别的锁(独占class类)
无论new多少个对象去访问该静态synchronized方法,都要排队一个个访问,竞争同一把锁(class这个锁)
package sync;
public class MultiThread {
private static int num = 0;
public static synchronized void printNum(String tag) {
try {
if(tag.equals("a")) {
num = 100;
System.out.println("tag a , set num over!");
Thread.sleep(1000);
System.out.println("tag " + tag + ", num = " + num);
}else {
num = 200;
System.out.println("tag b , set num over!");
Thread.sleep(1000);
System.out.println("tag " + tag + ", num = " + num);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
//新建两个对象m1 、m2
MultiThread m1 = new MultiThread();
MultiThread m2 = new MultiThread();
//新建第一个线程,调用m1对象的printNum()方法
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
m1.printNum("a");
}
});
//新建第二个线程,调用m2对象的printNum()方法
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
m2.printNum("b");
}
});
//同时启动两个线程
t1.start();
t2.start();
//是先执行完线程t1,再执行线程t2吗?
}
}
输出结果:
tag b , set num over!
tag b, num = 200
tag a , set num over!
tag a, num = 100
可以看到:
先执行完一个线程b,再执行下一个线程a
结论:
(1)static synchronized是类锁,锁住这个类