内容

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