Java多线程编程中的Synchronized

Synchronized,顾名思义,代表多个线程之间的同步。那么,在java编程中如何使用它呢?

我们假设这样一个情况:对于同一个变量synDemo,我们分别在2个不同的线程中调用synDemo.synMethord1()与synDemo.synMethord2()。

package com.cnblogs.gpcuster; /** * * @author Aaron.Guo * */ public class Tester { public static void main(String[] args) { final SynDemo synDemo = new SynDemo(); Thread thread1 = new Thread() { @Override public void run() { // TODO Auto-generated method stub super.run(); synDemo.synMethord1(); } }; Thread thread2 = new Thread() { @Override public void run() { // TODO Auto-generated method stub super.run(); synDemo.synMethord2(); } }; thread1.start(); thread2.start(); while (true) { try { Thread.sleep(1000); System.out.println("main"); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }

我们的SynDemo是这样定义的:

package com.cnblogs.gpcuster; /** * * @author Aaron.Guo * */ public class SynDemo{ public void synMethord1() { while(true) { try { Thread.sleep(1000); System.out.println("synMethord1"); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public void synMethord2() { while(true) { try { Thread.sleep(1000); System.out.println("synMethord2"); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }

我们的SynDemo对象没有任何特殊的定义,所以运行起来以后的情况如下:

synMethord2
synMethord1
main
synMethord2
synMethord1
main
synMethord2
synMethord1

接下来,我们给synMethord1添加上synchronized声明,运行情况还是与上次一样,因为我们只有一个线程在调用synMethord1的方法。

我们给synMethord2也添加上synchronized声明,SynDemo对象的代码修改

 

package com.cnblogs.gpcuster; /** * * @author Aaron.Guo * */ public class SynDemo{ public synchronized void synMethord1() { while(true) { try { Thread.sleep(1000); System.out.println("synMethord1"); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public synchronized void synMethord2() { while(true) { try { Thread.sleep(1000); System.out.println("synMethord2"); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }

这个时候,我们再运行程序,结果就不一样了:

main
synMethord1
main
synMethord1
main
synMethord1

我们发现,对于SynDemo对象,只有synMethord1运行了,而synMethord2却没有运行。这是应为在方法级别的synchronized声明将lock这个类对象的当前实例。所以在synMethord1运行结束unlock之前,当前实例是无法运行synMethord2的。这种方法级别的synchronized声明和以下的做法是等同的

 

package com.cnblogs.gpcuster; /** * * @author Aaron.Guo * */ public class SynDemo { public void synMethord1() { synchronized (this) { while (true) { try { Thread.sleep(1000); System.out.println("synMethord1"); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } public void synMethord2() { synchronized (this) { while (true) { try { Thread.sleep(1000); System.out.println("synMethord2"); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }

运行程序,结果与上次相同。

如果我们希望分别同步2个方法该如何处理?可以参考这个实现:

 

package com.cnblogs.gpcuster; /** * * @author Aaron.Guo * */ public class SynDemo { private Object flag1 = new Object(); private Object flag2 = new Object(); public void synMethord1() { synchronized (flag1) { while (true) { try { Thread.sleep(1000); System.out.println("synMethord1"); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } public void synMethord2() { synchronized (flag2) { while (true) { try { Thread.sleep(1000); System.out.println("synMethord2"); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }

 

运行程序,结果如我们预期:

main
synMethord2
synMethord2
main
synMethord1
main
synMethord1
synMethord2

 

关于Synchronized还有一些其他的话题,如static的问题,继承的问题,与volatile搭配使用等等,在网上都有很详细的说明,这里就不重复介绍了。

你可能感兴趣的:(java,thread,多线程,编程,object,Class)