访问同一个对象的同步方法与非同步方法
2014-01-06 14:23
211 查看
几个线程访问一个对象的方法,访问同步方法必须竞争,同时访问非同步方法可立即访问,不参与竞争
下面是实验代码
通过反射对三个方法的访问
下面是实验代码
通过反射对三个方法的访问
package synchronization; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class A implements Runnable { private int id = 0; private String name=null; private String str=null; private Object obj=null; public A(int id,String name){ super(); this.id = id; this.name=name; } public synchronized void a1() { try { System.out.println("a1-----begin-----"); Thread.sleep(5000); System.out.println("a1---11111"); System.out.println("a1-----end-----"); } catch (InterruptedException e) { e.printStackTrace(); } } public synchronized void a2() { try { System.out.println("a2-----begin-----"); Thread.sleep(5000); System.out.println("a2---222222"); System.out.println("a2-----end-----"); } catch (InterruptedException e) { e.printStackTrace(); } } public void a3() { System.out.println("a3-----begin-----"); System.out.println("a3---33333"); System.out.println("a3-----end-----"); } @Override public void run() { Method m=null; try { m=this.getClass().getMethod(name); System.out.println("线程"+id+"启动"); m.invoke(obj); } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getStr() { return str; } public void setStr(String str) { this.str = str; } public Object getObj() { return obj; } public void setObj(Object obj) { this.obj = obj; } }
package synchronization; public class TestSynchonized { public static void main(String[] args) throws InterruptedException { //同步探索 A a=new A(1,"a1"); a.setObj(a); //启动另一个线程,访问同步方法a1 new Thread(a).start(); Thread.sleep(200); //启动另一个线程,访问同步方法a2 a.setId(2); a.setName("a2"); new Thread(a).start(); Thread.sleep(200); //启动另一个线程,访问非同步方法a3 a.setId(3); a.setName("a3"); new Thread(a).start(); /** * 此处启动三个线程,a1、a2同步方法,a3非同步方法,每隔0.2s启动,此处是让子线程启动完成 * * 访问的结果,a1最先开始,由于a2与a1同步,争夺资源,a2不能访问; * a3非同步方法,a3 0.4s之后随后立即访问 * 随后4.6s之后a1访问完,释放锁对象,随后a2 * * * 结论:一个对象的同步方法,必须竞争,非同步方法不受同步方法干扰 */ } }
此处启动三个线程,a1、a2同步方法,a3非同步方法,每隔0.2s启动,此处是让子线程启动完成 访问的结果,a1最先开始,由于a2与a1同步,争夺资源,a2不能访问; a3非同步方法,a3 0.4s之后随后立即访问 随后4.6s之后a1访问完,释放锁对象,随后a2 结论:一个对象的同步方法,必须竞争,非同步方法不受同步方法干扰照常执行
相关文章推荐
- 同时创建多个线程,它们都访问一个对象中的同步方法,怎么确保第一个线程最先拿到对象锁,否则,怎么保证多个线程之间的有序通信
- 【Java面试题】26 多线程有几种实现方法?同步有几种实现方法? 当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法?
- 修改SQL数据库中表字段类型时,报“一个或多个对象访问此列”错误的解决方法
- 另一种方法是使用锁来同步访问对象
- 修改SQL数据库中表字段类型时,报“一个或多个对象访问此列”错误的解决方法
- 迭代器模式:就是提供一种方法对一个容器对象中的各个元素进行访问,而又不暴露该对象容器的内部细节。
- 第二章、对象及变量的并发访问 之 synchronized 同步方法(1)
- 修改SQL数据库中表字段类型时,报“一个或多个对象访问此列”错误的解决方法
- 第二章、对象及变量的并发访问 之 synchronized 同步方法(2)
- 本类的方法可以访问本类的任何一个对象的私有域、
- 修改SQL数据库中表字段类型时,报“一个或多个对象访问此列”错误的解决方法
- 应用程序中的所有线程都可以访问方法中的公用字段。要同步对公用字段的访问,您可以使用属性替代字段,并使用 ReaderWriterLock 对象控制访问。为此,请按照下列步骤操作:
- synchronized关键字修饰对象锁,同步与非同步对该方法的访问及修改
- android通过ksoap访问webservice方法传递一个复杂对象参数
- 关于java多线程中同步的问题(两个线程访问同一个实例类的两个同步方法,会不会互相影响)
- 简述原型链是什么,有什么用处?若想访问一个对象的原型,应该使用什么方法?
- Iterator 提供一种方法顺序访问一个对象中各个元素,而又不需要暴露该对象的内部表示
- 在iOS中有几种方法来解决多线程访问同一个内存地址的互斥同步问题
- 修改SQL数据库中表字段类型时,报“一个或多个对象访问此列”错误的解决方法
- 为什么一个对象调用的类方法可以访问该类其他对象的私有成员