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 没错就是这样.其他都类似,就不分析了.