1
  1. 使用 name、mark1、mark2、mark3 和 sum 变量创建一个 Student 类。
  2. 创建一个包含 4 个学生对象和一些值的 ArrayList。
  3. 创建一个 MarkEvaluation 线程和 ShowMark 线程。
  4. MarkEvaluation 应该计算每个学生的总分。
  5. ShowMark 线程应显示计算的总和。
  6. 使用 join 方法防止 ShowMark 线程在 MarkEvaluation 之前运行。

它不是家庭作业。正在做一些练习。这里他们要求我运行 2 个线程做不同的事情,但我不知道我们是否可以运行 2 个 run() 方法。我怎样才能执行 2 个不同的操作?对不起,我刚刚开始学习线程。这是我所做的,但它不完整。

import java.util.*;

class Student implements Runnable
 {
 public Student()
 {
     List<Object> list = new ArrayList<Object>();
     list.add("robin");
     list.add("ravi");
     list.add("raj");
     list.add("sam");
 }
 String name;
 int mark1=30,mark2=45,mark3=70,sum=0;

 public void run()
  {
    sum = mark1+mark2+mark3;
  }

}

public class Ch3Lu2Ex3
 {
  public static void main(String[] args) 
  {
    Student stu = new Student();
    Thread MarkEvaluation = new Thread(stu);
    MarkEvaluation.start();
    Thread ShowMark = new Thread();

}
}
4

3 回答 3

1

你在正确的轨道上。您现在要做的是创建另一个Runnable类来显示结果总和,并且您需要找到某种方法来共享来自MarkEvaluation线程的计算总和。我建议使用BlockingQueue, 因为该方法take()将阻塞,直到进入线程,满足您的最后一个要求而不必使用.sumputjoin()

明确地说,您需要 2 个实现 的类Runnable,1 个您已经拥有,另一个用于显示结果。您需要在它们之间共享 a ,并且您需要通过实例化 a和调用BlockingQueue来启动两个线程。希望这将使您走上正确的轨道,而无需简单地给您代码。Threadstart()

或者,您可以在线程上ShowMark Runnable保留对Student以及用于运行StudentMarkEvaluation上面调用)的线程的引用join,然后调用getSum()(或类似方法)从Student.

于 2013-01-13T05:16:12.113 回答
1

将其更改为

class Student implements Runnable {
...
}

class ShowMarkThread extends Thread {
    private final int sum;

    ShowMarkThread(int sum) {
        this.sum = sum;
    }

    @Override
    public void run() {
        System.out.println(sum);
    }
}

public class Ch3Lu2Ex3 {

    public static void main(String[] args) throws Exception {
        Student stu = new Student();
        Thread markEvaluation = new Thread(stu);
        markEvaluation.start();
        markEvaluation.join();
        new ShowMarkThread(stu.sum).start();
    }
}

此外,我建议制作 2 个单独的课程 - Student 和 MarkEvaluationThread,Student implements Runnable看起来很糟糕

于 2013-01-13T05:31:15.903 回答
1

正如@dicarlo2 所提到的, BlockingQueue 也可以解决您的问题。但我认为你以错误的方式处理这个问题。这是我的多线程解决方案。我在 ShowMark 类中添加了一个 System.out.println 语句,以便我们知道魔法正在发挥作用。您还会时不时地看到学生乱序打印。我希望这有帮助!

import java.util.ArrayList;
import java.util.List;


public class Main {

  public static void main(String[] args) {
    List<Student> students = new ArrayList<Student>();
    students.add(new Student("Alice", 10, 20, 30));
    students.add(new Student("Bob", 20, 30, 40));
    students.add(new Student("Carol", 30, 40, 50));
    students.add(new Student("Robin", 40, 50, 60));
    for (Student s : students) {
      Thread mkThread = new MarkEvaluation(s);
      mkThread.start();
      //Must at least start thread before starting ShowMark. 
      Thread smThread = new ShowMark(s, mkThread);
      smThread.start();
    }
  }

  private static class Student {
    String name;
    double mark1, mark2, mark3, sum;

    public Student(String name, double mark1, double mark2, double mark3) {
      this.name = name;
      this.mark1 = mark1;
      this.mark2 = mark2;
      this.mark3 = mark3;
    }
  }

  private static class MarkEvaluation extends Thread {
    Student stu;
    public MarkEvaluation(Student stu) {
      this.stu = stu;
    }
    @Override
    public void run() {
      super.run();
      stu.sum = stu.mark1 + stu.mark2 + stu.mark3;
    }
  }

  private static class ShowMark extends Thread {
    Thread thread;
    Student stu;
    public ShowMark(Student stu, Thread thread) {
      this.stu = stu;
      this.thread = thread;
    }
    @Override
    public void run() {
      super.run();
      // A thread is alive if it has been started and has not yet died.
      while (thread.isAlive()) {
        try {
          System.out.println("Waited for thread: " + thread.toString() + " to finish.");
          thread.join();
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
      System.out.println(stu.name + " " + stu.sum);
    }
  }

}
于 2013-01-13T06:14:58.837 回答