【问题标题】:java multithreading basic console programjava多线程基本控制台程序
【发布时间】:2020-07-25 19:28:56
【问题描述】:

我是多线程新手。所以这是我正在处理的问题:将学生证的最后四位数字存储在两个单独的班级中。例如,如果您的 ID 是 SE123456789,则将 67 存储在第一个 Thread1 类中,将 89 存储在 Thread2 类中,稍后将传递给 Factorial 类。 Thread1 类将 67 传递给 Factorial 类,printfactorial() 将打印从 1 到 67 的所有数字的阶乘。 Thread2 类将 89 传递给 Factorial 类,printfactorial() 将打印从 1 到 89 的所有数字的阶乘。 您应该在循环内的每次计算后使用 thread.sleep(10)。 如您所知,您不能在简单的整数或长类型变量中存储和打印大数的阶乘,因此您需要使用 BigInteger 来存储和打印非常长的数字。 printfactorial() 方法必须同步,以便首先打印 Thread1 的结果,然后计算并打印 Thread2 的结果。 这就是我到目前为止所做的。 我有四个不同的班级

Main
Factorial
Thread1
Thread2

Thread1 和 Thread2 都扩展了 Thread 类。 这是我目前写的代码:

主要

public class Main {
 public static void main(String args[]){
    Factorial factorial = new Factorial();  
    Thread1 t1 = new Thread1(factorial);
    Thread1 t2 = new Thread1(factorial);
    t1.start();
    t2.start();
 }
}

阶乘类

import java.math.BigInteger;
public class Factorial {
    public void printFactorial(int number){
        BigInteger bigInteger = new BigInteger("1");
        try{
            for(int i=1; i<=number; i++){
                bigInteger = bigInteger.multiply(BigInteger.valueOf(i));
                Thread.sleep(10); 
                System.out.println(bigInteger);
            }
        }catch(InterruptedException ex){
            System.out.println("the interruption has occurred in the thread");
        }
    }
}

线程1

package com.mycompany.factorial;
public class Thread1 extends Thread {
    Factorial factorial;
    Thread1(Factorial fact){
        factorial = fact;
    }
    @Override
    public void start(){
        synchronized(factorial){
            try{
                /*my ID is: SE170400080
                so the second last two digits are 00.
                **/
                factorial.printFactorial(00); //here's the problem
            }catch(Exception e){
                System.out.println("the interruption has occurred in the thread");
            }
        }
    }
}

线程2

package com.mycompany.factorial;

public class Thread2 extends Thread {
    Factorial factorial;
    Thread2(Factorial fact){
        factorial = fact;
    }
    @Override
    public void start(){
        synchronized(factorial){
            try{
                factorial.printFactorial(80);
              
            }catch(Exception e){
                System.out.println("the interruption has occurred in the thread");
            }
        }
    }
}

运行主程序后,它成功构建但不显示所需的输出。

非常感谢您的帮助,我已尽力保持重点。

1:

【问题讨论】:

  • 您确定您正在运行该项目而不仅仅是构建它吗?顺便说一句,您不需要同步对 Factorial.printFactorial 方法的访问,因为它不操作共享数据。
  • @AndrewVershinin 是的,我构建它而不是运行它。
  • 不要覆盖start()。如果你这样做,那么t1.start() 和t2.start() 调用只是调用你自己的代码,并且不会创建任何线程。改写 Thread.run() 方法。
  • 你说,“......我构建然后运行它。”是什么让你认为你正在运行它?为什么不在main(...) 一开始就在它做任何其他事情之前添加一个println("I am alive!") 语句?如果你没有看到“我还活着!”打印在控制台输出中,那么询问为什么没有打印其他内容是没有意义的。
  • Re, "...printFactorial(00); // 这就是问题所在" 这是作业的问题——你的导师显然没有考虑过这种情况——但我不认为这是您的代码有问题。您的 printFactorial 方法应该打印从 1 到 N 的所有数字的阶乘。嗯,没有从 1 到 0 的任何数字,所以如果 printFactorial(0) 不打印任何东西,那么它就完全按照作业所说的去做了。

标签: java multithreading


【解决方案1】:

不是一个完整的答案,但你需要知道这一点:

Thread 实例不是线程。线程 是操作系统中运行您的代码的对象。 Java Thread 实例是程序中的一个对象,您可以使用它来创建和管理操作系统线程。

Thread 实例在您调用t.start() 时创建操作系统线程。不要覆盖start() 方法,因为如果你这样做,那么它将永远不会创建线程。如果您覆盖 start(),您将只是调用 您 编写的方法。

当你调用正常 t.start() 方法时,它会创建一个新线程,那么新线程将调用t.run()。 run() 方法是您要覆盖的方法,因为它的代码将在新线程中执行。

【讨论】:

  • 谢谢,但问题仍未解决我尝试了不同的数字而不是 00 它工作正常,但我正在弄清楚为什么它没有打印出从 1 到 80 的阶乘。就像你说的没有数字在从 1 到 0 的范围内。
【解决方案2】:

您的代码中有一些错误:

  1. 重写run 方法,而不是start:start 只启动你的线程,但实际运行的代码属于run 方法。 Oracle 的website 上有一个不错的小教程。

  2. 在main 中,您创建了Thread1 的两个实例,这可能是复制粘贴错误

【讨论】:

  • 回复,“1...运行...开始。”你说的是真的,但你还没有告诉 OP 为什么重写 start() 是不好的,或者为什么“正在运行的实际代码属于 run() 方法”。再详细一点就好了。
  • 回复。 “2....” 使用Thread1 类的两个实例的程序没有任何问题。 Thread11 类和 Thread2 类是相同的。无论main() 例程是使用Thread1 的两个实例还是Thread2 的两个实例或每个实例一个实例,程序输出都是相同的。
  • @SolomonSlow 好吧,“为什么”——因为它是这样工作的。不过,添加了指向教程的链接。至于第二个,它们不一样——它们用不同的参数调用printFactorial。
  • Re "3..." 您建议 OP 实施与任务要求实施不同的东西。作业说:“从 1 到给定的所有数字。”从 1 到 0 的范围内有 no 个数字。因此,正确的解决方案在给定零时应该不打印任何阶乘。 OP 应该 做的是插入一个不同的号码,并添加一条评论说:“这不是我的实际学生 ID。我的实际 ID 以 00 结尾,但这是一个错误的号码使用因为....”
  • @SolomonSlow 至于第三个,公平点,去掉了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-12
  • 2023-03-04
  • 1970-01-01
  • 2014-09-28
  • 1970-01-01
相关资源
最近更新 更多