线程试题:当一个线程进入一个对象的一个synchronized方法

J2EE 码拜 10年前 (2015-04-16) 1286次浏览 0个评论

 当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法?
分几种情况:
     1.其他方法前是否加了synchronized关键字,如果没加,则能。
     2.如果这个方法内部调用了wait,则可以进入其他synchronized方法。
     3.如果其他个方法都加了synchronized关键字,并且内部没有调用wait,则不能。
     4.如果其他方法是static,它用的同步锁是当前类的字节码,与非静态的方法不能同步,因为非静态的方法用的是this。

前面三点都好理解,第四点看的我稀里糊涂,完全不懂啥意思。
  求更详细的讲解,如果能配合代码就是极好的

线程试题:当一个线程进入一个对象的一个synchronized方法
20分
public class A {

	/**
	 * 静态方法
	 */
	public synchronized static void staticMethod(){}

	/**
	 * 实例方法
	 */
	public synchronized void instanceMethod(){}
	public static void main(String[] args) {

		//A实例的创建过程
		Class c = Class.forName("A");
		A a1 = c.newInstance();
		A a2 = c.newInstance();
		A a3 = c.newInstance();
	}
}

如上代码所示,你看一看main方法里面A实例的创建过程,这个要先理解
staticMethod这个静态方法,无法你实例化多少次,它都只是存在一个,就像Class c指向的对象,它在jvm中也只会存在一个,staticMethod方法锁住的是c指向的实例。

instanceMethod这个实例方法,你创建多少个A实例,这些实例都存在各自的instanceMethod方法,这个方法前加synchronized关键词,会锁住该instanceMethod方法所在的实例。如a1的instanceMethod方法会锁住a1指向的实例,a2的instanceMethod会锁住a2指向的实例。

由此得出结论,staticMethod与instanceMethod锁住的对象是不可能相同的,这就是两个方法不能同步的原因。

线程试题:当一个线程进入一个对象的一个synchronized方法
算是明白一些了,自己写了个测试代码。 第四点表达的意思应该是:线程1调用非静态的synchronized方法,线程2调用静态的synchronized方法,两者互不影响。 注:如果线程1和2,同为非静态或静态,则必须等一个线程执行完,再执行下一个。
求大神指正。。。。(以前语文没学好,现在后悔了)

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class StaticThread
{
	public static void main(String[] args)
	{
		ExecutorService service = Executors.newFixedThreadPool(2);
		List<Future<String>> resultList = new ArrayList<Future<String>>();
		SyncObj syncObj = new SyncObj();

		for(int i=0; i<2; i++){
			Future<String> future = service.submit(new CallThread(syncObj, i));
			resultList.add(future);
		}

		for(int j=0; j<resultList.size(); j++){
			try
			{
				System.out.println(resultList.get(j).get());
			}
			catch (InterruptedException e)
			{
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			catch (ExecutionException e)
			{
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		service.shutdown();
	}

}

class CallThread implements Callable<String>{

	private int id;
	private SyncObj syncObj;
	CallThread(SyncObj syncObj, int id){
		this.id = id;
		this.syncObj = syncObj;
	}
	@Override
	public String call() throws Exception
	{

		if(id%2 ==0){
			syncObj.getFun1(id);
		}else{
			syncObj.getStatic1(id);
		}

		return "线程 "+id+"执行完毕!";
	}

}

class SyncObj{
	public synchronized static void getStatic1(int id){
		System.out.println("线程 "+id+"进入getStatic1()!");
		for (int i = 0 ; i < 9999999; i--);
		System.out.println("线程 "+id+"退出getStatic1()!");
	}
	public synchronized static void getStatic2(int id){
		System.out.println("线程 "+id+"进入getStatic2()!");
		for (int i = 0 ; i < 9999999; i--);
		System.out.println("线程 "+id+"退出getStatic2()!");
	}
	public synchronized void getFun1(int id) throws InterruptedException{
		System.out.println("线程 "+id+"进入getFun1()!");
//		this.wait();
		for (int i = 0 ; i < 999999; i--);
		System.out.println("线程 "+id+"退出getFun1()!");
	}
	public  synchronized void getFun2(int id){
		System.out.println("线程 "+id+"进入getFun2()!");
		for (int i = 0 ; i < 9999999; i--);
		System.out.println("线程 "+id+"退出getFun2()!");
	}
}
线程试题:当一个线程进入一个对象的一个synchronized方法
引用 1 楼 wu244534279 的回复:
public class A {

	/**
	 * 静态方法
	 */
	public synchronized static void staticMethod(){}

	/**
	 * 实例方法
	 */
	public synchronized void instanceMethod(){}
....
}

如上代码所示,你看一看main方法里面A实例的创建过程,这个要先理解
staticMethod这个静态方法………

谢谢!~ 


CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明线程试题:当一个线程进入一个对象的一个synchronized方法
喜欢 (0)
[1034331897@qq.com]
分享 (0)

文章评论已关闭!