单例模式:保证一个类仅有一个势力,并提供一个访问它的全局访问点,在编程实现的时候,我想让两个线程t1,、t2分别访问该实例,而且是互斥的访问,虽然Instance的互斥实现了,但是关于createSingletonInstance()的互斥访问却没有实现,请问这是问什么,希望各位大虾给予解答,thx。 /** *Singleton.java */ package shejimoshi.singleton; /** * @author xuhongbin * @data2014年9月21日上午10:37:55 */ public class Singleton { private static Singleton instance; private Singleton(){//构造方法让其private, 这就毒死了外界利用new 创建此类实例的可能 } public static synchronized Singleton GetInstance(){ if(instance == null){ instance = new Singleton(); System.out.println(Thread.currentThread().getName()+"创建了instance实例"); } return instance; } } 其次是线程类以及主函数: /** *TestSingleton.java */ package shejimoshi.singleton; /** * @author xuhongbin * @data2014年9月21日下午2:30:37 */ public class TestSingleton implements Runnable{ public static int i; Singleton s; /* (non-Javadoc) * @see java.lang.Runnable#run() */ @Override public void run() { createSingletonInstance(); } public synchronized void createSingletonInstance(){ s = Singleton.GetInstance(); i++; try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"线程调用了一个Singleton对象"); System.out.println("第"+i+"次调用Singleton对象。。。。。"); } /** * @param args */ public static void main(String[] args) { Thread t1 = new Thread(new TestSingleton(), "ss1"); Thread t2 = new Thread(new TestSingleton(), "ss2"); t1.start(); t2.start(); } } 一直出现这样的结果: 而我想要线程互斥的访问,也就是后两句应该一个是“第1次调用……”, “第2次调用……” |
|
大家快来帮忙啊!
|
|
帮帮忙啊!为何没有人呢???
|
|
真的没人么???
|
|
10分 |
我测试了一下发现,是你的Thread.sleep(1000)的问题,如下图,当ss1进入createSingletonInstance函数时,i会变为1,会因为sleep函数而停在这里一会儿,这个时候ss2就进入了createSingletonInstance函数,i还是会加1,即这个时候i是2.而且这个时候两个线程都还在sleep函数这一块,没有往下执行,所以之后两个线程往下执行之后,两个语句输出来的就都是i=2的输出语句。这样解释你应该理解了吧
|
但是我给函数createSingletoninstance加锁了呀,同一时刻应该改只有一个线程可以访问啊,为何线程ss1,ss2都可以调用该函数?
|
|
但是我给函数createSingletoninstance加锁了呀,同一时刻应该改只有一个线程可以访问啊,为何线程ss1,ss2都可以调用该函数? |
|
10分 |
对于这个问题,首先要了解对象锁,你每次创建了新的对象,就会有新的对象锁,每次线程使用的都是新的对象。试试这样写:
TestSingleton s = new TestSingleton(); Thread t1 = new Thread(s, "ss1"); Thread t2 = new Thread(s, "ss2"); Thread t3 = new Thread(s, "ss3"); t1.start(); t2.start(); t3.start(); 这样就是多个线程调用一个对象的同步方法 |
10分 |
最基本的都不懂,你对对象的方法加了锁 这个意思就是同一个实例会互斥,你new了两个对象 怎么互斥啊 哥!
|
谢谢啊。刚刚才找到问题的本质。 |
|
谢谢啊,刚刚才找到问题的本质 |
|
10分 |
方法前加锁是保证不会有两个线程同时执行该类的方法,你的这个情况类本身就是一个线程,没有什么实际意义
i是你这个线程自身的成员变量,如果你想让两个线程互斥访问这个成员变量,在这个成员变量上加锁sychronized(i) |
public static void main(String[] args) {
TestSingleton ts = new TestSingleton(); Thread t1 = new Thread(ts, “ss1”); Thread t2 = new Thread(ts, “ss2”); t1.start(); t2.start(); } |
|
谢谢大伙儿啊
|