内容
1.synchronized工作原理
2.synchronized修饰方法
3.一个小面试题(输出结果目前看不懂)
4.类锁
5.死锁
一.synchronized的工作原理
synchronized(this){}
t1线程执行到此处,遇到了synchronized关键字,就会去找this的对象锁,如果找到this对象锁,则进入同步语句块中执行程序,当同步语句块中的代码执行结束之后,t1线程归还this的对象锁。
在t1线程执行同步语句块的过程中,如果t2线程也过来执行这些代码,也遇到synchronized关键字,所以也去找this的对象锁,但是该对象锁被t1线程持有,只能在这等待this对象的归还
二.synchronized修饰方法
使用示例
public synchronized void withdraw(double money) {
double after = balance - money;
//延迟
try{Thread.sleep(1000);}catch(Exception e) {}
//更新余额
this.setBalance(after);
}
当synchronized关键字添加到成员方法上的时候,线程拿走的也是this的对象锁。但是这种方式不推荐,不如前面那一种同步的更精细
三.一个小面试题(输出结果目前看不懂)
/*
* 面试题
*/
public class 测试程序 {
public static void main(String[] args) throws InterruptedException {
//创建mc对象
MyClass mc = new MyClass();
Processor p = new Processor(mc);
//创建线程t1,t2并命名
Thread t1 = new Thread(p);
t1.setName("t1");
Thread t2 = new Thread(p);
t2.setName("t2");
//启动线程
t1.start();
//延迟(保证t1先启动,并执行run)
Thread.sleep(1000);
t2.start();
}
}
//创建线程
class Processor implements Runnable
{
MyClass mc;
Processor(MyClass mc){
this.mc = mc;
}
public void run() {
//如果是t1线程,就执行m1
if(Thread.currentThread().getName().equals("t1"));{
mc.m1();
}
//如果是t2线程,就执行m2
if(Thread.currentThread().getName().equals("t2")) {
mc.m2();
}
}
}
class MyClass{
public synchronized void m1() {
//休眠
try {
Thread.sleep(2000);
}catch(Exception e) {}
System.out.println("m1");
}
//m2方法会等m1方法结束,t1,t2共享同一个mc,并且m1和m2方法上都有synchronized
public synchronized void m2() {
System.out.println("m2");
}
}
上面这个程序本应该输出
m1
m2但是实际上输出了
m1
m1
m2
想了好久也不知道什么原因。
刚才讲的是对象锁,下面讲类锁
四.类锁
1.如何使用
synchronized添加到静态方法上,线程执行此方法的时候会找类锁
2.使用示例
public class 测试程序 {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new Processor());
Thread t2 = new Thread(new Processor());
t1.setName("t1");
t2.setName("t2");
t1.start();
//延迟,保证t1先执行
Thread.sleep(1000);
t2.start();
}
}
//创建线程
class Processor implements Runnable
{
public void run() {
if("t1".equals(Thread.currentThread().getName())) {
MyClass.m1();
}
if("t2".equals(Thread.currentThread().getName())) {
MyClass.m2();
}
}
}
class MyClass{
//synchronized添加到静态方法上,线程执行此方法的时候会找类锁
public synchronized static void m1() {
try {
Thread.sleep(10000);
}catch(Exception e) {}
System.out.println("m1...");
}
//不会等m1结束,因为该方法没有被synchronized修饰
/*public static void m2() {
System.out.println("m2...");
}
*/
//这个m2方法会等m1方法结束之后才执行,因为该方法有synchronized
//线程执行该代码需要类锁,而类锁只有一个
public synchronized static void m2() {
System.out.println("m2...");
}
}
就会输出
m1...
m2...
五.死锁
public class 测试程序 {
public static void main(String[] args) throws InterruptedException {
Object o1 = new Object();
Object o2 = new Object();
Thread t1 = new Thread(new T1(o1,o2));
Thread t2 = new Thread(new T2(o1,o2));
t1.start();
t2.start();
}
}
class T1 implements Runnable{
Object o1;
Object o2;
T1(Object o1,Object o2){
this.o1 = o1;
this.o2 = o2;
}
public void run() {
synchronized(o1) {
try{Thread.sleep(1000);}catch(Exception e) {}
synchronized(o2) {
}
}
}
}
class T2 implements Runnable{
Object o1;
Object o2;
T2(Object o1,Object o2){
this.o1 = o1;
this.o2 = o2;
}
public void run() {
synchronized(o2) {
try {
Thread.sleep(1000);
}catch(Exception e) {}
synchronized(o1) {
}
}
}
}
这个程序就进入一个僵持状态t1刚锁住o1,准备锁o2时,o2已经被t2锁住,此时t2还想锁o1