您的位置:首页 > 其它

访问同一个对象的同步方法与非同步方法

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

结论:一个对象的同步方法,必须竞争,非同步方法不受同步方法干扰照常执行
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐