1,锁重用,如果一个方法用synchronized修饰,并且这个方法中引入了其他的用synchronized修饰的方法,那么线程执行这个方法的时候,会自动获取方法中的其他方法锁。
例子:
public class SynchronzedClass {
public synchronized void a(){
b();
}
public synchronized void b(){
System.out.println("b method");
}
}
public class SynMainClass {
public static void main(String[] args) {
Thread t = new Thread();
final SynchronzedClass syb = new SynchronzedClass();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
syb.a();
}
});
t1.start();
}
}
结果:b method
2,同步不具有继承性
例子:
public class FatherClass {
public synchronized void a(){
try {
System.out.println("father begin :"+Thread.currentThread().getName());
Thread.sleep(5000);
System.out.println("father end :"+Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private class SunClass extends FatherClass{
@Override
public void a() {
try {
System.out.println("son begin:"+Thread.currentThread().getName());
Thread.sleep(5000);
System.out.println("son end:"+Thread.currentThread().getName());
super.a();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private class Thread1 extends Thread{
private SunClass sunClass;
public Thread1(SunClass sunClass){
this.sunClass = sunClass;
}
@Override
public void run() {
sunClass.a();
super.run();
}
}
private class Thread2 extends Thread{
private SunClass sunClass;
public Thread2(SunClass sunClass){
this.sunClass = sunClass;
}
@Override
public void run() {
sunClass.a();
super.run();
}
}
public static void main(String[] args) {
FatherClass f = new FatherClass();
SunClass son = f.new SunClass();
Thread1 t1 = f.new Thread1(son);
Thread2 t2 = f.new Thread2(son);
t1.setName("a");
t2.setName("b");
t1.start();
t2.start();
}
}
结果:son begin:a
son begin:b
son end:b
son end:a
father begin :b
father end :b
father begin :a
father end :a
可以看到子类继承的方法在多线程的情况下是不同步的,但是他们的父类被继承的方法是同步的,这个例子是
用内部类的方法实现的,此规则在非内部类情况下依然适用。
3,当一个线程出现异常的时候,会释放他所持有的锁
public class ExceptionThread {
private class Demo{
private int a=0;
public synchronized void test(){
if(Thread.currentThread().getName().equals("a")){
System.out.println(12/a);
}else{
System.out.println("b method");
}
}
}
private class Thread1 extends Thread{
private Demo e;
Thread1(Demo e){
this.e = e;
}
@Override
public void run() {
e.test();
super.run();
}
}
private class Thread2 extends Thread{
private Demo e;
Thread2(Demo e){
this.e = e;
}
@Override
public void run() {
e.test();
super.run();
}
}
public static void main(String[] args) {
ExceptionThread e = new ExceptionThread();
Demo d = e.new Demo();
Thread1 t1 = e.new Thread1(d);
Thread2 t2 = e.new Thread2(d);
t1.setName("a");
t2.setName("b");
t1.start();
t2.start();
}
}
结果:Exception in thread "a" b method
java.lang.ArithmeticException: / by zero
at com.qsfs.thread.synch.use.ExceptionThread$Demo.test(ExceptionThread.java:8)
at com.qsfs.thread.synch.use.ExceptionThread$Thread1.run(ExceptionThread.java:22)
4,(1)synchronized 方法()与synchronized(this){}等效的 ,锁的都是对象
public class ThisThread {
public void test(){
synchronized(this){
try {
System.out.println("begin"+Thread.currentThread().getName());
Thread.sleep(3000);
System.out.println("begin"+Thread.currentThread().getName());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private class Thread1 extends Thread{
private ThisThread e;
Thread1(ThisThread e){
this.e = e;
}
@Override
public void run() {
e.test();
super.run();
}
}
private class Thread2 extends Thread{
private ThisThread e;
Thread2(ThisThread e){
this.e = e;
}
@Override
public void run() {
e.test();
super.run();
}
}
public static void main(String[] args) {
ThisThread d = new ThisThread();
ThisThread d1 = new ThisThread();
Thread1 t1 = d.new Thread1(d);
Thread2 t2 = d.new Thread2(d1);
t1.setName("a");
t2.setName("b");
t1.start();
t2.start();
}
}
(2)synchronized static 方法()与syncjronized(类.class)等效的,锁的都是类,此类生成的对象都会被锁住(方法,或者相同的钥匙)
public class ClassSynchronizedThread {
private synchronized static void test1() throws InterruptedException{
System.out.println("begin method Synchronized"+Thread.currentThread().getName());
Thread.sleep(3000);
System.out.println("end method Synchronized"+Thread.currentThread().getName());
}
private void test2() throws InterruptedException{
synchronized(ClassSynchronizedThread.class){
System.out.println("begin synchronized block"+Thread.currentThread().getName());
Thread.sleep(3000);
System.out.println("end synchronized block"+Thread.currentThread().getName());
}
}
private class Thread1 extends Thread{
private ClassSynchronizedThread e;
Thread1(ClassSynchronizedThread e){
this.e = e;
}
@Override
public void run() {
try {
e.test1();
e.test2();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
super.run();
}
}
private class Thread2 extends Thread{
private ClassSynchronizedThread e;
Thread2(ClassSynchronizedThread e){
this.e = e;
}
@Override
public void run() {
try {
e.test1();
e.test2();
} catch (InterruptedException e) {
e.printStackTrace();
}
super.run();
}
}
public static void main(String[] args) {
ClassSynchronizedThread d1 = new ClassSynchronizedThread();
ClassSynchronizedThread d2 = new ClassSynchronizedThread();
Thread1 t1 = d1.new Thread1(d1);
Thread2 t2 = d1.new Thread2(d2);
t1.setName("a");
t2.setName("b");
t1.start();
t2.start();
}
}
5,一个类中可能有很多个内部类,这些类中很有可能就会有一些霸道的,比如一个内部类中方法的锁的对象可能就是其他内部类的对象,那么访问这个方法的线程与访问这个对象中静态方法的线程是同步执行的
public class objec {
class A{
private B b;
private void test(B b){
this.b = b;
synchronized(b){
for(int i=0;i<5;i++){
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
}
}
class B{
public synchronized void test1(){
for(int i=0;i<5;i++){
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
}
public static void main(String[] args) {
objec o = new objec();
final A a = o.new A();
final B b = o.new B();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
a.test(b);
}
},"a");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
b.test1();
}
},"b");
t1.start();
t2.start();
}
}
结果:
a:0
a:1
a:2
a:3
a:4
b:0
b:1
b:2
b:3
b:4
静态内部类和普通内部类都适用
6,synchronized(对象),如果对象不变,即使是属性变了,也不会影响效果