关于java多线程中同步的问题(两个线程访问同一个实例类的两个同步方法,会不会互相影响)
2008-03-14 13:35
603 查看
题目有点长,不知道大家能不能明白!
首先得出的结论是:
它们是互相影响的,因为在一个实例类中同步方法锁定的是该实例类对象,因此会互相影响.
下面是我做的一个测试:
(1)创建一个实例类:
package com.lenove.testThread;
public class SynchronizationObject {
public SynchronizationObject(){
}
public synchronized void runSynchronizationMethod0(){
System.out.println("this is start test0!");
//该循环的目地只有一个,就是可以使当前方法在一定时间内交出执行线程
for(int i = 0;i < 10000000;i++){
}
System.out.println("this is end test0!");
}
public synchronized void runSynchronizationMethod1(){
System.out.println("this is start test1!");
for(int i = 0;i < 10000000;i++){
}
System.out.println("this is end test1!");
}
}
(2)创建一个调用的线程类
package com.lenove.testThread;
public class testThread implements Runnable {
Thread th;
int type;
SynchronizationObject so;
public testThread(SynchronizationObject so,int type){
this.so = so;
th = new Thread(this);
th.start();
}
public void run() {
if(type == 1)
so.runSynchronizationMethod1();
else
so.runSynchronizationMethod0();
}
public static void main(String[] args){
SynchronizationObject so = new SynchronizationObject();
new testThread(so,1);
new testThread(so,0);
}
}
程序执行后.无论执行多少次,结果为:
this is start test1!
this is end test1!
this is start test0!
this is end test0!
这时如果将SynchronizationObject 实例对象的任意一个方法的同步去掉(即去掉方法前面的synchronized),执行结果将出现一定的变化
第一次执行: 第二次执行:
this is start test1! this is start test1!
this is start test0! this is end test1!
this is end test1! this is start test0!
this is end test0! this is end test0!
这时结果出现运行时刻输出结果不一致的情况,这说明同时访问一个实例对象的不同的同步方法,相互之间是有影响的,它们之间使用的锁就是该实例对象.
运行情况分析:
当第一个线程执行时,运行到runSynchronizationMethod1()方法时,由于该方法是synchronizated,这时会先将so锁定,然后执行方法内的语句,中间由于大循环,线程交出执行权,交由第二个线程执行,第二个线程执行时,运行到runSynchronizationMethod0()方法,由于该方法也是synchronizated,这时该对象试图对so进行锁定,但由于之间该对象已被锁定,因此其锁定失败,需要等待第一个线程对so进行解锁,这里线程调度将控制权交给第一个线程执行,第一个线程执行完毕runSynchronizationMethod1()方法,这时对so进行解锁,这时线程交到第二个线程,第二个线程对so进行锁定操作,并可以锁定成功,因此继续执行完runSynchronizationMethod0()方法中的内容,.并进行解锁.
首先得出的结论是:
它们是互相影响的,因为在一个实例类中同步方法锁定的是该实例类对象,因此会互相影响.
下面是我做的一个测试:
(1)创建一个实例类:
package com.lenove.testThread;
public class SynchronizationObject {
public SynchronizationObject(){
}
public synchronized void runSynchronizationMethod0(){
System.out.println("this is start test0!");
//该循环的目地只有一个,就是可以使当前方法在一定时间内交出执行线程
for(int i = 0;i < 10000000;i++){
}
System.out.println("this is end test0!");
}
public synchronized void runSynchronizationMethod1(){
System.out.println("this is start test1!");
for(int i = 0;i < 10000000;i++){
}
System.out.println("this is end test1!");
}
}
(2)创建一个调用的线程类
package com.lenove.testThread;
public class testThread implements Runnable {
Thread th;
int type;
SynchronizationObject so;
public testThread(SynchronizationObject so,int type){
this.so = so;
th = new Thread(this);
th.start();
}
public void run() {
if(type == 1)
so.runSynchronizationMethod1();
else
so.runSynchronizationMethod0();
}
public static void main(String[] args){
SynchronizationObject so = new SynchronizationObject();
new testThread(so,1);
new testThread(so,0);
}
}
程序执行后.无论执行多少次,结果为:
this is start test1!
this is end test1!
this is start test0!
this is end test0!
这时如果将SynchronizationObject 实例对象的任意一个方法的同步去掉(即去掉方法前面的synchronized),执行结果将出现一定的变化
第一次执行: 第二次执行:
this is start test1! this is start test1!
this is start test0! this is end test1!
this is end test1! this is start test0!
this is end test0! this is end test0!
这时结果出现运行时刻输出结果不一致的情况,这说明同时访问一个实例对象的不同的同步方法,相互之间是有影响的,它们之间使用的锁就是该实例对象.
运行情况分析:
当第一个线程执行时,运行到runSynchronizationMethod1()方法时,由于该方法是synchronizated,这时会先将so锁定,然后执行方法内的语句,中间由于大循环,线程交出执行权,交由第二个线程执行,第二个线程执行时,运行到runSynchronizationMethod0()方法,由于该方法也是synchronizated,这时该对象试图对so进行锁定,但由于之间该对象已被锁定,因此其锁定失败,需要等待第一个线程对so进行解锁,这里线程调度将控制权交给第一个线程执行,第一个线程执行完毕runSynchronizationMethod1()方法,这时对so进行解锁,这时线程交到第二个线程,第二个线程对so进行锁定操作,并可以锁定成功,因此继续执行完runSynchronizationMethod0()方法中的内容,.并进行解锁.
相关文章推荐
- Java线程:线程的同步与锁 一、同步问题提出 线程的同步是为了防止多个线程访问一个数据对象时,对数据造成的破坏。 例如:两个线程ThreadA、ThreadB都操作同一个对象Foo对
- 一个类有两个方法,其中一个是同步的,另一个是非同步的; 现在又两个线程A和B,请问:当线程A访问此类的同步方法时,线程B是否能访问此类的非同步方法?
- EF(Entity Framework)发生错误”正在创建模型,此时不可使用上下文“的解决办法。 正在创建模型,此时不可使用上下文。如果在 OnModelCreating 方法内使用上下文或如果多个线程同时访问同一上下文实例,可能引发此异常。请注意不保证 DbContext 的实例成员和相关类是线程安全的。 临时解决了这个问题,在Context的构造函数中,禁用了自动初始化:
- java基础问题---java中有几种方法可以实现一个线程?用什么关键字修饰同步方法? stop()和suspend()方法为何不推荐使用
- 利用线程的同步和互斥解决两个消费者两个生产者一个临界区问题
- 在iOS中有几种方法来解决多线程访问同一个内存地址的互斥同步问题
- 借助cookie实现子网页修改父网页内容遇到的问题:同一个浏览器访问相同页面,会互相影响。 (已解决)
- 2.2.9同一个类的不同静态方法不同实例不同线程是同步的
- Java中一个类里面有两个用synchronized修饰的非静态方法,不同的线程中的实例访问这两个方法时会发生什么?
- 同时创建多个线程,它们都访问一个对象中的同步方法,怎么确保第一个线程最先拿到对象锁,否则,怎么保证多个线程之间的有序通信
- 学习Java的第一步是安装好JDK,写一个Hello World, 其实JDK的学习没有那么简单,关于JDK有两个问题是很容易一直困扰Java程序员的地方:一个是CLASSPATH的问题,其实从原理上来说,是要搞清楚JRE的ClassLoader是如何加
- 关于创建一个输入端和两个输出端遇到问题的解决
- 关于jQuery EasyUI 中刷新Tab选项卡 后一个页面变形的问题的解决方法
- Win2003下关于c#读写Excel时,出现存取被拒&Excel实例化出错的一个解决方法
- 看到的一个关于hashmap线程不安全的实例
- 关于在静态方法中访问非静态内部类的问题
- 一个httpclient4实例跨域访问会报错,谁知道在什么情况下会出现这个问题?
- 关于使用Spring声明式事务时,在类的内部方法互相调用时,Spring无法拦截内部方法调用,导致事务不起作用的问题研究
- 编写一个Book类,该类至少有name和price两个属性。该类要实现Comarable接口,在接口的compareTo()方法中规定两个Book类实例的大小关系为二者的price属性的大小关系。
- 关于在myeclipse中用jsp访问实体bean的一个问题的解决(Exception sending context initialized event to listener instance of class)