懒汉式单例和多线程问题

huyiyu 2016-09-07 11:15:13
class huyiyu
{
public static void main(String[] args)
{
// Single s1 = Single.getInstance();
// Single s2 = Single.getInstance();
// System.out.println(s1 == s2);

GetSingle[] Gs = new GetSingle[10];

for(int i = 0; i < Gs.length;i++)
Gs[i] = new GetSingle();
for(int i = 0; i < Gs.length;i++)
Gs[i].start();

for(int i = 0; i < Gs.length;i++)
{
System.out.println(Gs[i].getS1());
}
}
}


class Single
{
private Single()
{

}
private static Single obj = null;
public static synchronized Single getInstance()
{
if(obj == null)
obj = new Single();

return obj;
}
}
class GetSingle extends Thread
{
private Single s1;
public void run()
{
while(s1 == null)//为什么会返回空 我都上锁了
this.s1 = Single.getInstance();
}
public Single getS1()
{
return s1;
}
}
首先代码 如上图 然后 发现数组内其实会获取到空指针 我实在找不到错误 求指正为什么
输出结果:
null
Single@4e25154f
Single@4e25154f
Single@4e25154f
Single@4e25154f
Single@4e25154f
Single@4e25154f
Single@4e25154f
Single@4e25154f
Single@4e25154f
...全文
230 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
huyiyu 2016-09-08
  • 打赏
  • 举报
回复
其实那个代码就是我写的,只是想不到为什么为空 昨天朋友提醒说是主线程先运行了的缘故我就知道了 不过还是谢谢批评指正
引用 2 楼 NewMoons 的回复:
楼主完全没有理解这个程序单例下加锁的意义,那是为了防止多线程下同时进入getInstance方法创建多个实例,而不是保证取得一个不为空的实例。 至于第一个为什么为空,因为getS1()执行的时候Single.getInstance()还没执行呢,这说明你根本对线程的基本概念还没明白!增加下面代码,再看看结果。
try {
			Thread.sleep(500);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		for (int i = 0; i < Gs.length; i++) {
			System.out.println(Gs[i].getS1());
		}
一句话,楼主,对于多线程你还没学会走,就想学会跑,还是再多看看线程方面的基础知识吧。
橙子赖 2016-09-08
  • 打赏
  • 举报
回复
楼上和楼上的楼上正解。楼主可到lechenggu.com学习免费的多线程章节。或度娘搜素乐橙谷
rendason 2016-09-08
  • 打赏
  • 举报
回复
引用 2 楼 NewMoons 的回复:
楼主完全没有理解这个程序单例下加锁的意义,那是为了防止多线程下同时进入getInstance方法创建多个实例,而不是保证取得一个不为空的实例。 至于第一个为什么为空,因为getS1()执行的时候Single.getInstance()还没执行呢,这说明你根本对线程的基本概念还没明白!增加下面代码,再看看结果。
try {
			Thread.sleep(500);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		for (int i = 0; i < Gs.length; i++) {
			System.out.println(Gs[i].getS1());
		}
一句话,楼主,对于多线程你还没学会走,就想学会跑,还是再多看看线程方面的基础知识吧。
楼上说的很清楚了,由于在多线程环境下,GetSingle的run()和getS1()不是由同一个线程调用,哪个先调用完全是根据处理器调度随机的,在我这就输出的是10个null
NewMoons 2016-09-08
  • 打赏
  • 举报
回复
楼主完全没有理解这个程序单例下加锁的意义,那是为了防止多线程下同时进入getInstance方法创建多个实例,而不是保证取得一个不为空的实例。 至于第一个为什么为空,因为getS1()执行的时候Single.getInstance()还没执行呢,这说明你根本对线程的基本概念还没明白!增加下面代码,再看看结果。
try {
			Thread.sleep(500);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		for (int i = 0; i < Gs.length; i++) {
			System.out.println(Gs[i].getS1());
		}
一句话,楼主,对于多线程你还没学会走,就想学会跑,还是再多看看线程方面的基础知识吧。
  • 打赏
  • 举报
回复
这个和上不上锁没关系,第一次获取值时,还没有线程为他赋值,当然是null了

62,628

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧