1 简介
synchronized在方法内,同步代码块,传入对象,使用的是对象锁,传入class对象,使用的是类锁
作用于普通方法,也是对象锁,当前对象
作用于静态方法,是类锁
2 同步方法示例
2.1
两个synchronized 修饰的普通方法
public class SychTest1 {
static class Phone{
synchronized void sendEmail(){
System.out.println("EMAIL");
}
synchronized void sendMsg(){
System.out.println("MSG");
}
}
public static void main(String[] args) {
Phone p = new Phone();
new Thread(()->{
p.sendEmail();
}).start();
try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); }
new Thread(()->{
p.sendMsg();
}).start();
}
}
执行结果,持有同一个锁对象p
EMAIL
MSG
2.2
两个synchronized 修饰的普通方法,sendEmail睡了2秒
public class SychTest2 {
static class Phone{
synchronized void sendEmail(){
try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); }
System.out.println("EMAIL");
}
synchronized void sendMsg(){
System.out.println("MSG");
}
}
public static void main(String[] args) {
Phone p = new Phone();
new Thread(()->{
p.sendEmail();
}).start();
try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); }
new Thread(()->{
p.sendMsg();
}).start();
}
}
执行结果,持有同一个锁对象p,所以还是sendEmail先执行
EMAIL
MSG
2.3
一个同步方法,一个普通方法
public class SychTest3 {
static class Phone{
synchronized void sendEmail(){
try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); }
System.out.println("EMAIL");
}
void sendMsg(){
System.out.println("MSG");
}
}
public static void main(String[] args) {
Phone p = new Phone();
new Thread(()->{
p.sendEmail();
}).start();
try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); }
new Thread(()->{
p.sendMsg();
}).start();
}
}
执行结果
MSG
EMAIL
2.4
两个同步方法,但是是两个不同的对象p和p2去调用同步方法
public class SychTest4 {
static class Phone{
synchronized void sendEmail(){
try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); }
System.out.println("EMAIL");
}
synchronized void sendMsg(){
System.out.println("MSG");
}
}
public static void main(String[] args) {
Phone p = new Phone();
Phone p2 = new Phone();
new Thread(()->{
p.sendEmail();
}).start();
try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); }
new Thread(()->{
p2.sendMsg();
}).start();
}
}
执行结果,持有的是不同的锁对象p和p2
MSG
EMAIL
2.5
两个静态同步方法
public class SychTest5 {
static class Phone{
synchronized static void sendEmail(){
try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); }
System.out.println("EMAIL");
}
synchronized static void sendMsg(){
System.out.println("MSG");
}
}
public static void main(String[] args) {
Phone p = new Phone();
new Thread(()->{
p.sendEmail();
}).start();
try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); }
new Thread(()->{
p.sendMsg();
}).start();
}
}
执行结果,持有的是同一个类锁
EMAIL
MSG
2.6
两个静态同步方法,两个对象p和p2去调用
public class SychTest6 {//?
static class Phone{
synchronized static void sendEmail(){
try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); }
System.out.println("EMAIL");
}
synchronized static void sendMsg(){
System.out.println("MSG");
}
}
public static void main(String[] args) {
Phone p = new Phone();
Phone p2 = new Phone();
new Thread(()->{
p.sendEmail();
}).start();
try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); }
new Thread(()->{
p2.sendMsg();
}).start();
}
}
执行结果,持有的是同一个类锁,和哪个对象去调用无关
EMAIL
MSG
2.7
一个静态同步,一个非静态同步
public class SychTest7 {
static class Phone{
synchronized static void sendEmail(){
try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); }
System.out.println("EMAIL");
}
synchronized void sendMsg(){
System.out.println("MSG");
}
}
public static void main(String[] args) {
Phone p = new Phone();
new Thread(()->{
p.sendEmail();
}).start();
try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); }
new Thread(()->{
p.sendMsg();
}).start();
}
}
执行结果,一个持有类锁,一个持有对象锁
MSG
EMAIL
2.8
一个静态同步方法,一个非静态同步方法,两个对象去调用
public class SychTest8 {
static class Phone{
synchronized static void sendEmail(){
try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); }
System.out.println("EMAIL");
}
synchronized void sendMsg(){
System.out.println("MSG");
}
}
public static void main(String[] args) {
Phone p = new Phone();
Phone p2 = new Phone();
new Thread(()->{
p.sendEmail();
}).start();
try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); }
new Thread(()->{
p2.sendMsg();
}).start();
}
}
执行结果,一个持有类锁,一个持有对象锁
MSG
EMAIL
3 同步代码示例
3.1
传入class对象
public class SychTest13 {
public static synchronized void aa() {
System.out.println("aaa");
}
public static void main(String[] args) throws InterruptedException {
new Thread(()->{
synchronized (SychTest13.class){
try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }
System.out.println("aaaaaaaaaaaa");
}
}).start();
new Thread(()->{
synchronized (SychTest13.class){
System.out.println("bbbbbbbbbb");
}
}).start();
}
}
执行结果
aaaaaaaaaaaa
bbbbbbbbbbb
3.2
传入同一个对象t1
public class SychTest14 {
public static synchronized void aa() {
System.out.println("aaa");
}
public static void main(String[] args) throws InterruptedException {
SychTest13 t1 = new SychTest13();
new Thread(()->{
synchronized (t1){
try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }
System.out.println("aaaaaaaaaaaa");
}
}).start();
new Thread(()->{
synchronized (t1){
System.out.println("bbbbbbbbbb");
}
}).start();
}
}
执行结果
aaaaaaaaaaaa
bbbbbbbbbbb
3.3
传入对象t1和t2
public class SychTest15 {
public static synchronized void aa() {
System.out.println("aaa");
}
public static void main(String[] args) throws InterruptedException {
SychTest13 t1 = new SychTest13();
SychTest13 t2 = new SychTest13();
new Thread(()->{
synchronized (t1){
try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }
System.out.println("aaaaaaaaaaaa");
}
}).start();
new Thread(()->{
synchronized (t2){
System.out.println("bbbbbbbbbb");
}
}).start();
}
}
执行结果
bbbbbbbbbb
aaaaaaaaaaaa