? 当多个线程共同访问一个对象中的实例变量时,有可能会出现非线程安全,运行的结果也可能是混乱的,解决的办法就是加锁。同步机制可以使用synchronized关键字实现。
1.1 synchronized取得的锁都是对象锁
public?class?MyObject?{
?? synchronized?public?void?methodA()?{
?? try?{
????? System.out.println("开始执行,线程名:"
????? +?Thread.currentThread().getName());
????? //?不会释放锁
????? Thread.sleep(1000);
????? System.out.println("方法执行完毕!");
?? }?catch?(InterruptedException?e)?{
????? e.printStackTrace();
? }
?}
}
public?class?ThreadA?extends?Thread?{
?private?MyObject?myObject;
?public?ThreadA(MyObject?myObject)?{
??? super();
? this.myObject?=?myObject;
?}
?
?@Override
? public?void?run()?{
? super.run();
? myObject.methodA();
? }
}
public?class?ThreadB?extends?Thread?{
? private?MyObject?myObject;
? public?ThreadB(MyObject?myObject)?{
? ?? super();
???? this.myObject?=?myObject;
? }
? @Override
? public?void?run()?{
?? super.run();
?? myObject.methodA();
? }
}
?
public?class?TestMyObject?{
? public?static?void?main(String[]?args)?{
??? MyObject?myObject?=?new?MyObject();
??? ThreadA?threadA?=?new?ThreadA(myObject);
??? threadA.setName("A线程");
??? ThreadB?threadB?=?new?ThreadB(myObject);
??? threadB.setName("B线程");
??? threadA.start();
??? threadB.start();
? }
}
运行结果是:
开始执行,线程名:A线程
方法执行完毕!
开始执行,线程名:B线程
方法执行完毕!
???可以看到执行结果永远是执行完第一个线程的输出再执行另一个线程输出,当一个线程访问一个对象的synchronized方法时,其余线程如果也要访问该 synchronized方法,则需要等待,但是如果对象里有其它未加synchronized关键字的方法,则可以异步执行。并且 synchronized还具体锁重入的功能,即一个线程可以再次请求某个对象的锁。
1.2?静态同步方法
???当synchronized关键字修饰的方法同时也被static修饰后,获得的锁不是对象锁,而是这个方法所在的类的Class对象。
???一个类不管生成多少个对象,都属于同一个Class对象,因此当线程分别访问同一个类的两个对象的两个static,synchronized方法时,它们的执行顺序也是同步的。? 1.3?synchronized同步代码块
当对方法进行加锁时,会出现这样的问题,如果这个方法执行时间过长,当导致其余线程必须长时间等待,这个时候可以使用同步代码块来解决。
synchronized(object){
}
?? 表示对object对象加锁,当然这也可以是其它的对象,如果是不同的对象,执行是异步的,如果是同一个对象,则同步。可以看到,synchronized代码块只锁一部分代码,方法中的其它语句也是可以异步执行的。
二:结论
1:synchronized关键字是给对象上锁,如果该对象里有其它非synchronized方法,那么其它线程可以异步执行该非synchronized方法。
2:synchronized有锁重入功能,也就是一个对象里面的两个synchronized方法,当访问第一个synchronized方法时还可以访问第二个synchronized方法。
3:synchronized加在static修饰的方法时,是对该对象所在类的Class上锁。
4:synchronized同步代码块比较灵活,可以对不同对象上锁。
原文:http://tanjie090508.iteye.com/blog/2287925