java求随机0到0.9的浮点数_JAVA 线程输出0~0.9之间随即浮点数

博客讨论了在Java中如何使用多线程生成0到0.9之间的随机浮点数,并解释了时间片、线程调度算法以及`sleep()`函数的工作原理。在示例代码中,两个线程共享全局变量`i`,通过同步确保正确顺序执行。提出了使用`sleep(0)`放弃时间片以优化线程调度的建议。
摘要由CSDN通过智能技术生成

匿名用户

1级

2011-05-06 回答

1L说的理论才是正确的,2L说的东西也是对的,但是2L说的和你现在出现的这个错误无关,我想1个时间片对于这个程序来说,是绝对可以把几行代码执行完的,从CPU指令的时间上也可以推出来。从上面可以非常明显的看出来,关键是第一次输出的问题,其实你的多线程代码问题很多,但是在你这个程序里表现不出来。

为了解释一些东西,先解释一些概念。其实你说这个问题如果往深处说就复杂了,只能简单的去说

时间片:CPU对线程的执行,是通过分配时间片来实现的,即每个线程每次运行都有一个时间限制,不能超过这个时间,这个时间的最大程度就是时间片(如果不考虑抢占的问题,时间片是一定的,即每个线程每次都运行一个完整的时间片的时间)

线程调度算法:CPU对线程的调度,是有一个算法来决定调度系统所有线程的先后顺序(这里为了方便解释,我全部认为是核心线程,而不存在用户线程,用户线程是通过进程间接调度的,即CPU并不知道有用户线程存在,而核心线程是CPU直接知道的并且直接调度的)。那算法是怎么样的,历史上有无数种线程调度算法,作为一个程序员,你只能认为是不可知的,即你要保证无论哪个线程先执行,程序都是一致的。这个算法由操作系统决定。

取你的代码的关键部分

SLEEP函数:这个函数到底做了什么,两件事,1放弃时间片立即让操作系统进行下一次调度,2定时让自己变得可以重新调度(你设定的时间内此线程是不可调度的)

Tsleep1 T1= new Tsleep1();

Tsleep2 T2= new Tsleep2();

T1.start();

T2.start();

你的程序里绝对T1会先执行完一次循环,这个基本是肯定的,因为要执行的操作肯定用不了半个时间片就足够了,所以时间片造成的放弃调度的问题基本不太可能(针对你的代码)。所以第一个输出一定是输出0,也确实这样。

try{

sleep(1000);

}

好了,解释输出。

前者关键是下面的

0

This is i=0

This is i=1

1

0

This is i=0

1

This is i=1

在你T1第一次输出0后,调用SLEEP放弃了时间片,这个时候T2运行输出了This is i=0,这个过程不太可能有同步的问题,因为相对1S来说,时间片实在是太短了,而且你执行操作极少,基本保证了是原子的。

关键是第3行开始,现在经过前面的调度,T2进入睡眠了,为什么现在反而T2先比T1先运行,明明是T2在睡眠嘛?原因是,你的两个线程都是用户级线程(一般核心级线程要显示的指明,因为开销过大),这种情况下,CPU是先调度进程,然后进程才决定让谁先运行。在T2睡眠的时候,CPU调度其他进程,等到再次轮到你的进程的时候,T1和T2都已经“醒”了,这个时候操作系统要根据自己的算法去决定,这个算法并不是先进先出的,即使你T1先醒,T2后醒,但是两者没有优先级的区别,操作系统视为平等,可以自由选择调度哪一个。 并且,即使两者都是核心级线程,也可能另外其他程序长期占用了CPU而使得下一次调度的时候对两者的调度发生细微的顺序差异。所以即使你T1先START,T2后START,仍然无法保证以后T1先于T2,需要进行同步。同步使用信号量的方法就足够了。

两个线程共享全局变量i,初始化为0,自己同步就行了,反而效率更高些。别说面相对象就不使用全局变量,同步那绝对在多个线程之间避免不了共享。

伪代码,只是表达意思,同时保证了每次操作是原子的也保证了顺序,虽然2L保证了每次操作的原子性,但是没能够保证顺序,当然,可能是看不出来效果的。

T1执行时首先

while{

if(i==0)

{

i++;

执行你想的操作

sleep(0);//放弃时间片就好了,没必要等那么久

}

else

{

sleep(0);//说明T1完后又再次先于T2被调度了,立即放弃时间片

}

}

对于T2

while{

if(i==1)

{

i--;

执行你想的操作

sleep(0)

}

else

{

sleep(0);//立即放弃时间片

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值