将必须同步的代码使用synchronized代码块(对象/类锁)
对象锁
对象锁也叫方法锁,是针对一个对象实例的,它只在该对象的某个内存位置声明一个标识该对象是否拥有锁,所有它只会锁住当前的对象,而并不会对其他对象实例的锁产生任何影响,不同对象访问同一个被synchronized修饰的方法的时候不会阻塞
OutMe.java
public class OutMe {
// 这也是对象锁
// synchronized void sync_out_Some() {
// try {
// System.out.println(Thread.currentThread().getName());
// Thread.sleep(4000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// }
// 这是对象锁:减小锁粒度,第二种形式就比较好
void sync_out_Some() {
synchronized (this) {
try {
System.out.println(Thread.currentThread().getName());
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
void out_some() {
System.out.println(Thread.currentThread().getName());
}
}
package test;
Test2.java
package test;
public class Test2 {
public static void main(String[] args) {
OutMe outMe=new OutMe();
OutMe outMe2=new OutMe();
Thread out1Thread=new Thread(new Runnable() {
public void run() {
outMe.sync_out_Some();
}
},"out1Thread_1");
/**对象锁:
* 注销 注释(1)运行结果: out1Thread_1输出后 4秒以后
* 输出 out2Thread_1 最后还要执行sleep() 4秒后 程序结束:同一对象的同步;
*
* 注销 注释(2)运行结果:同时输出out2Thread_1、out1Thread_1:
* 对象锁只针对同一对象,不同对象不起作用
*
* 注销 注释(3)运行结果:同时输出out2Thread_1、out1Thread_1:
* out_some没有加synchronized修饰
*/
Thread out2Thread=new Thread(new Runnable() {
public void run() {
// outMe.sync_out_Some(); (1)
// outMe2.sync_out_Some(); (2)
// outMe.out_some(); (3)
}
},"out2Thread_1");
out1Thread.start();
out2Thread.start();
}
}
类锁
不管多少个对象,多少个对象,共用一把多,且只有一把,不管怎么调用,都会同步
OutMe.java
package test;
public class OutMe {
// 这也是类锁:就是在void 上加le static
// synchronized static void sync_out_Some() {
// try {
// System.out.println(Thread.currentThread().getName());
// Thread.sleep(4000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// }
void sync_out_Some() {
// 就这里不同:对象锁括号里面的是this
// 类锁 里面也可以为 this.getClass() 或 类名.class :获得的都是该类型OutMe的类型类
// 里面有OutMe的所有信息:直接父类、全称、实现的所有接口等等
synchronized (OutMe.class) {
try {
System.out.println(Thread.currentThread().getName());
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
void out_some() {
System.out.println(Thread.currentThread().getName());
}
}
/**
* 类锁
* 注销 注释(1)或 (2):
* 都是 out1Thread_1输出后 4秒以后 输出 out2Thread_1:他们都是同一个类
*/