Java synchronized简要总结

来源:互联网 发布:老友网南宁网络电视台 编辑:程序博客网 时间:2024/04/30 11:10

synchronized修饰的方法,记住:
1.非静态方法
同步锁synchronized无论是用于方法(synchronized method)还是类(synchronized class)
(1)如果该类对象是唯一的,比如

//..省略两个被同步锁修饰的test1和test2方法和main方法和类名testsyn

final testsyn myt = new testsyn();//唯一的

Thread test1 = new Thread( new Runnable() { public void run() { myt.test1(); } }, “test1” ); //该类对象

Thread test2 = new Thread( new Runnable() { public void run() { myt.test2(); } }, “test2” ); //该类对象

此时线程test1执行方法test1时线程test2将无法访问test2方法,原因是将类比作房屋而里面的同步锁即为房间的锁,一个类仅有一把钥匙,此时线程test1先拿到钥匙进房屋开始访问,而线程2没用只有等线程1访问完才能执行。附代码如下:

public class testsyn
{
public synchronized void test1()
{
int i = 5;
while( i– > 0)
{
System.out.println(Thread.currentThread().getName() + ” : ” + i);
try
{
Thread.sleep(500);
}
catch (InterruptedException ie)
{
}
}
}

public  synchronized void test2()   {       int i = 5;         while( i-- > 0)       {           System.out.println(Thread.currentThread().getName() + " : " + i);              try            {                  Thread.sleep(500);             }            catch (InterruptedException ie)            {             }        }    

}

public static void main(String[] args)   {        final   testsyn myt = new testsyn();     final   testsyn myt2 = new testsyn();      Thread test1 = new Thread(  new Runnable() {  public void run() {  myt.test1();  }  }, "test1"  );        Thread test2 = new Thread(  new Runnable() {  public void run() { myt.test2();   }  }, "test2"  );        test1.start();        test2.start();    }   

}
输出结果如下:
test1 : 4
test1 : 3
test1 : 2
test1 : 1
test1 : 0
test2 : 4
test2 : 3
test2 : 2
test2 : 1
test2 : 0

注意:synchronized锁类和锁非静态方法效果是一样的,看下面:
public class TestSynchronized
{
public void test1()
{
synchronized(this)
{
int i = 5;
while( i– > 0)
{
System.out.println(Thread.currentThread().getName() + ” : ” + i);
try
{
Thread.sleep(500);
}
catch (InterruptedException ie)
{
}
}
}
}
public synchronized void test2()
{
int i = 5;
while( i– > 0)
{
System.out.println(Thread.currentThread().getName() + ” : ” + i);
try
{
Thread.sleep(500);
}
catch (InterruptedException ie)
{
}
}
}
public static void main(String[] args)
{
final TestSynchronized myt1 = new TestSynchronized();
final TestSynchronized myt2 = new TestSynchronized();
Thread test1 = new Thread( new Runnable() { public void run() { myt1.test1(); } }, “test1” );
Thread test2 = new Thread( new Runnable() { public void run() { myt1.test1(); } }, “test2” );
test1.start();;
test2.start();

}
}
输出结果如下:
test1 : 4
test1 : 3
test1 : 2
test1 : 1
test1 : 0
test2 : 4
test2 : 3
test2 : 2
test2 : 1
test2 : 0

(2)但是如果该类被不同对象引用,如下:

public class testsyn
{
public synchronized void test1()
{
int i = 5;
while( i– > 0)
{
System.out.println(Thread.currentThread().getName() + ” : ” + i);
try
{
Thread.sleep(500);
}
catch (InterruptedException ie)
{
}
}
}

public  synchronized void test2()   {       int i = 5;         while( i-- > 0)       {           System.out.println(Thread.currentThread().getName() + " : " + i);              try            {                  Thread.sleep(500);             }            catch (InterruptedException ie)            {             }        }    

}

public static void main(String[] args)   {        final   testsyn myt = new testsyn();     final   testsyn myt2 = new testsyn();      Thread test1 = new Thread(  new Runnable() {  public void run() {  myt.test1();  }  }, "test1"  );        Thread test2 = new Thread(  new Runnable() {  public void run() { myt2.test2();   }  }, "test2"  );        test1.start();        test2.start();    }   

}
输出结果如下:
test1 : 4
test2 : 4
test1 : 3
test2 : 3
test1 : 2
test2 : 2
test1 : 1
test2 : 1
test1 : 0
test2 : 0

发现线程互不干扰,很简单,理解为两个房屋两把钥匙,那自然不会影响咯.

2.静态方法
明白静态是所有类共有的,静态方法在JVM刚加载的时候就编译过了,在程序的运行过程中随时可以调用…不需要去实例化某个对象然后再去调用,可以直接用类名去调用…不过你想一下,在JVM刚加载的进修就编译过了也就是说它一直存在着…也就是说它一直占用这内存中的地址空间,所以说也是比较占资源的,这和非静态方法是不一样的,所以,直接上代码看结果:

public class testsyn
{
public static synchronized void test1()
{
int i = 5;
while( i– > 0)
{
System.out.println(Thread.currentThread().getName() + ” : ” + i);
try
{
Thread.sleep(500);
}
catch (InterruptedException ie)
{
}
}
}

public  synchronized void test2()   {       int i = 5;         while( i-- > 0)       {           System.out.println(Thread.currentThread().getName() + " : " + i);              try            {                  Thread.sleep(500);             }            catch (InterruptedException ie)            {             }        }    

}

public static void main(String[] args)   {        final   testsyn myt = new testsyn();     final   testsyn myt2 = new testsyn();      Thread test1 = new Thread(  new Runnable() {  public void run() {  myt.test1();  }  }, "test1"  );        Thread test2 = new Thread(  new Runnable() {  public void run() { myt.test1();   }  }, "test2"  );        test1.start();        test2.start();    }   

}
输出结果:

test1 : 4
test1 : 3
test1 : 2
test1 : 1
test1 : 0
test2 : 4
test2 : 3
test2 : 2
test2 : 1
test2 : 0

上述代码引用同一个对象的同一个方法(还是静态方法),会被锁,很正常,如果是不同对象的静态方法,应该还是会锁:

public class testsyn
{
public static synchronized void test1()
{
int i = 5;
while( i– > 0)
{
System.out.println(Thread.currentThread().getName() + ” : ” + i);
try
{
Thread.sleep(500);
}
catch (InterruptedException ie)
{
}
}
}

public  synchronized void test2()   {       int i = 5;         while( i-- > 0)       {           System.out.println(Thread.currentThread().getName() + " : " + i);              try            {                  Thread.sleep(500);             }            catch (InterruptedException ie)            {             }        }    

}

public static void main(String[] args)   {        final   testsyn myt = new testsyn();     final   testsyn myt2 = new testsyn();      Thread test1 = new Thread(  new Runnable() {  public void run() {  myt.test1();  }  }, "test1"  );        Thread test2 = new Thread(  new Runnable() {  public void run() { myt2.test1();   }  }, "test2"  );        test1.start();        test2.start();    }   

}
输出结果:
test1 : 4
test1 : 3
test1 : 2
test1 : 1
test1 : 0
test2 : 4
test2 : 3
test2 : 2
test2 : 1
test2 : 0

这很好理解,但是如果引用的不是同一个对象的话,那肯定不会被锁,现在看下如果是两个静态,显然肯定被锁,看下:

public class testsyn
{
public static synchronized void test1()
{
int i = 5;
while( i– > 0)
{
System.out.println(Thread.currentThread().getName() + ” : ” + i);
try
{
Thread.sleep(500);
}
catch (InterruptedException ie)
{
}
}
}

public static synchronized void test2()   {       int i = 5;         while( i-- > 0)       {           System.out.println(Thread.currentThread().getName() + " : " + i);              try            {                  Thread.sleep(500);             }            catch (InterruptedException ie)            {             }        }    

}

public static void main(String[] args)   {        final   testsyn myt = new testsyn();     final   testsyn myt2 = new testsyn();      Thread test1 = new Thread(  new Runnable() {  public void run() {  myt.test1();  }  }, "test1"  );        Thread test2 = new Thread(  new Runnable() {  public void run() { myt.test2();   }  }, "test2"  );        test1.start();        test2.start();    }   

}
结果:
test1 : 4
test1 : 3
test1 : 2
test1 : 1
test1 : 0
test2 : 4
test2 : 3
test2 : 2
test2 : 1
test2 : 0
没错就是这样.其他都类似,就不分析了.

1 0