我的java小程序线程没有按照想象中那样输出,哪位大侠能告诉我错误的原理?

作者&投稿:藏冯 (若有异议请与网页底部的电邮联系)
dos运行java线程程序时。各线程不是同时执行 求高手解答。。~

线程的执行是有CPU时间片的,线程A拿到CPU执行时间,在这个有限的时间里面,能够执行完线程A的所有内容,然后线程B拿到执行时间,线程B执行完毕

要么吧for循环的数值加大

要么使用线程wait方法

对,它本身就是一个线程,main方法就是一个线程

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);//立即放弃时间片
}
}

在你的这个程序里面线程启动的顺序,并不一定是线程的执行顺,线程的执行次序和是否被打断不由程序控制,所以会出现这种情况。
你可以给线程设置优先级试试

cpu执行线程是按照时间片执行的,

轮到Thread1执行 ------ 0

轮到Thread2执行 ------ This is 0 ;

轮到Thread1执行,在一秒的时候cpu把时间片给Thread2,Thread1没有输出0,Thread2获得时间片输出,This is 1,就会出现不想发生的情况。

。。。

避免情况,加锁:
加锁作用是不执行完毕本线程,不把时间片交给其他线程。

package com.test;

public class Tsleep {
public static void main(String[] args) {

Object o = new Object();

Tsleep1 T1 = new Tsleep1(o);
Tsleep2 T2 = new Tsleep2(o);
T1.start();
T2.start();
}
}

class Tsleep1 extends Thread {
Object o;

public Tsleep1(Object o) {
this.o = o;
}

public void run() {

for (int i = 0; i < 10; i++) {
synchronized (o) {
System.out.println(i);
try {
sleep(1000);
} catch (Exception e) {
}
}
}
}

}

class Tsleep2 extends Thread {
Object o;

public Tsleep2(Object o) {
this.o = o;
}

public void run() {

for (int i = 0; i < 10; i++) {
synchronized (o) {
System.out.println("This is i=" + i);
try {
sleep(1000);
} catch (Exception e) {
}
}
}
}
}

你这是调用的线程 线程的时间片不是你控制的 并不一定是Tsleep1执行一次Tsleep2执行一次,Tsleep1和Tsleep2是打乱顺序执行的,你每次运行的结果都肯能不一样。 二楼正解


Java小程序与Java应用程序之间有何差别
1、小应用程序只能在与Java兼容的容器中运行,可以嵌入在HTML网页内,在网络上发布,当网页被浏览时,在浏览器中运行。小应用程序的运行还受到严格的安全限制,例如它不能访问用户计算机上的文件。Java应用程序没有这些限制,也不支持网页嵌入和下载运行。2、小应用程序和应用程序在代码编写上也有很大的差异...

谁能帮我编写个JAVA小程序呀 急!!急 !!急!!!
没有一个人来回答?我给你说说思路吧:首先呢,你得有个显示界面吧,panel之类的,然后呢,你需要画个矩形吧,那就用组件(component)的getGraphics方法来获取图形对象(graphics),然后用图形对象自己的draw方法来画矩形,参数自己设置吧。下面呢,就是在窗体上放一个按钮吧,点击按钮后触发事件里就是上面...

java小程序,为什么Person类前 加了public后 就运行不了了啊? 去掉之后...
因为java程序是从一个public类的main函数开始执行的,(其实是main线程),就像C程序是从main()函数开始执行一样。只能有一个public类是为了给类装载器提供方便。一个public 类只能定义在以它的类名为文件名的文件中。class a 表示默认的访问级别,即只有包内的其他类能访问它 (严格来说应该是 ...

java编写一个小程序
<!-- function volidate(){ var myform=document.forms[0];if(myform.elements[0].value=="javalearner" && myform.elements[1].value=="happy"){ document.write("javahappy");} else { alert("输入的不正确");} } --> 用户名 密码 ...

java中未初始化小程序是什么意思
问题应该是在这里:choi.add(getParameter("st1")); choi.add(getParameter("st2")); choi.add(getParameter("st3")); choi.add(getParameter("st4"));改成:choi.add("st1"); choi.add("st2"); choi.add("st3"); choi.add("st4");...

求用Java编一个小程序
class Retangle{ private double length;private double width;\/\/构造函数 Retangle(double length,double width){ this.length = length;this.width = width;} \/\/方法 public double getArea(){ return length*width;} public double getGirth(){ return 2*(length+width);} public static void ...

如何禁用或启用Java小程序?
看你是什么浏览器了 1、IE浏览器开启关闭JavaScript方法:在IE界面菜单栏中“工具”中选择“Internet选项”–“安全”选项卡–选择“Internet”(蓝色的小地球)–“自定义级别”–找到“脚本”下的“Java小程序脚本”中进行启用。如下图所示,设置完成后,重新打开浏览器设置即可生效。2、360浏览器开启Ja...

java se一段小程序那里错 了
public class NoSuchMethodErrorextends IncompatibleClassChangeError当应用程序试图调用类(静态或实例)的指定方法,而该类已不再具有该方法的定义时,抛出该异常。通常由编译器捕获该错误;仅当类定义发生不相容的更改时,在运行时才会发生该错误。JDK上面说的……你这个main()JVM应该没法用吧,所以才报错...

JAVA,小程序,没听懂,求助,大佬帮写一下!
然后在这个包下定义一个时钟类,名为Clock,设置它的三个成员变量,创建带参构造方法以及题目所说的show()方法,这个类就完成了。接着定义测试类(名为:TestClass),测试类中要存在main方法,这样才能使程序能在控制台中运行。在这个类中创建时钟类对象,利用构造方法初始化设置你所需的参数,并调用...

求java小程序代码,500行左右。。大作业用。追加50
import java.awt.*;import java.awt.event.*;import javax.swing.*;class mypanel extends Panel implements MouseListener { int chess[][] = new int[11][11];boolean Is_Black_True;mypanel(){ Is_Black_True = true;for(int i = 0;i < 11;i++){ for(int j = 0;j < 11;j++...

固始县19169273492: java线程问题,为什么我的程序得不到想要的结果(线程1先运行结束,才到线程2运行,可结果不是这样) -
拔新复方: 优先级不准?你理解什么叫线程优先级吗?线程你只要不告诉它等待,它是不会等其他线程先结束的.什么是线程,线程天生就是并行运行分支,哪怕你给它最低的优先级,那它也只是在同一时刻相比其他线程被执行的几率较低,而完全没有道...

固始县19169273492: java thread线程怎么按照顺序执行 -
拔新复方: 这个程序的执行顺序不不一定的,它的执行顺序还跟线程分的时间片有关CPU运算的时间 是分时间片 分给不同的线程的 一个线程执行完 或者用完了当前它分到的那个时间片 他就得让出CPU给其他线程使用啦!线程化是允许多个活动共存于...

固始县19169273492: 我的JAVA小程序有问题,帮忙看看
拔新复方: 你的程序是错误的,首先是两次对p1.x赋值了,这个只是笔误, 第二就是用read方法,read方法一次只读取一个字符,返回的是字符的ASCII码,例如输入1 返回49 输入a返回97 ,他一次只读如一个字符,如果直接按下enter键,就相当于输入两个字符,即回车和换行两个字符,对应的ASCII码是13,10 不能用System.in的read方法,改用BufferedReader的readline方法,以下是改了之后的程序,字数限制,放到补答里了

固始县19169273492: java线程的小问题 -
拔新复方: 首先说明,你的程序逻辑并没有问题,只是 System.out.println 放置的位置有些问题.你可能对于下面的输出结果感到有些困惑:Sender put : 1 Receiver get : 1Sender put : 2Sender put : 3 Rece...

固始县19169273492: java线程问题 -
拔新复方: 你这个线程程序是对的.而且你对抢占式调度系统的理解是没有错误的.因为系统是随即分配时间片的.所以每次点击运行执行的结果是不一样的.而你所说的结果只是其中的一个.可能在你的程序过程中,你始终...

固始县19169273492: java线程问题
拔新复方: 当然存在,任何一个Java的运行时都存在一个主线程,也就是main()函数的线程,还有几个daemon线程,一般用作垃圾回收使用.

固始县19169273492: Java线程问题 -
拔新复方: 你只要记住线程是受CPU调度的,而CUP都是有时间片轮换的,也就是给每一个线程分配的都有时间片.而线程在进入就绪状态后,就等着CPU分时间片给它,所以这东西基本上都是没什么顺序的,看CPU高兴先分给哪个线程了.并且就算一个线程执行完,它又回到就绪状态,再和其他线程一起等待,其结果有可能是它又重新被调用,从而接着又运行一遍.

固始县19169273492: java项目中线程死掉问题 -
拔新复方: 是否有报错,是否有死锁?分析原因需要源代码,运行环境,运行状况,日志信息等等. 自己写程序监测吧,常规工具只能监测到程序,监测不到程序里的线程的

固始县19169273492: Java线程问题,求高手解释下,思路不清晰的就算了 -
拔新复方: 俩个线程抢占式运行,Thread-0输出0还没有执行自加运算时T1抢占线程运行输出结果也是0,然后T0运行自加count=2,此时线程被t1得到来不及输出Thread-0:2 ,t1得到机会...

固始县19169273492: java线程的一些困惑
拔新复方: 这位朋友,根据您的问题解答如下,如有不明之处可以继续补充: JAVA多线程执行并没有顺序保证,说是多线程一起执行,但对于单核CPU来说还是有先后顺序的,只不过大多时候都是交替执行的.

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网