当前位置: 首页 > 知识库问答 >
问题:

通过扩展Java中共享同一对象的线程类来创建多个线程

芮明知
2023-03-14

我正在学习多线程的基础知识,并且正在编写一个程序来理解使用两种创建线程的方法之间的区别。

我已经读到,使用Runnable允许多个线程共享同一个对象,并希望在扩展线程时尝试类似的事情。因此,在创建了Demo2的新对象之后,我将引用传递给了线程构造函数(类似于我们在Runnable中所做的)。

当objT1,tT1,tT2将总和的值增加到3时,我达到了我想要达到的目标。但是在打印当前线程的名称时,它只打印demo2。1。我以为将要打印的线程名称是demo2。1,t1,t2,因为我在构造函数中传递了这些名称。

    class Main {
    public static void main(String args[]) {
        Demo1 objR1 = new Demo1();
        Demo2 objT1 = new Demo2("demo2.1");

        Thread tT1 = new Thread(objT1,"t1");
        Thread tT2 = new Thread(objT1,"t2");

        Thread tR1 = new Thread(objR1,"tR1");
        Thread tR2 = new Thread(objR1,"tR2");
    
        objT1.start();
        tT1.start();
        tT2.start();

        tR1.start();
        tR2.start();
    }
}


class Demo1 implements Runnable {

    int sum = 0;

    synchronized void calculate() {
        sum = sum +1;   
    }

    public void run()
    {
        calculate();    
        System.out.print(Thread.currentThread().getName()); 
        System.out.println(" "+sum);
    }
}

class Demo2 extends Thread {

    int sum = 0;

    Demo2(String n) {
        super(n);   
    }
    
    synchronized void calculate() {
        sum = sum +1;       
    }

    public void run()
    {
        calculate();        
        System.out.println(this.getName()+" "+sum);
    }
}

输出:

demo2.1 1
demo2.1 2
demo2.1 3
tR1 1
tR2 2

所以我的问题是——这个片段是否创建了3个线程?如果是,那么为什么每个线程没有3个不同的名称呢。如果没有,那么这些语句的作用是什么。

Demo2 objT1 = new Demo2("demo2.1");
Thread tT1 = new Thread(objT1,"t1");
Thread tT2 = new Thread(objT1,"t2"); 

我知道这一定很琐碎,但我在教程中找不到答案。提前谢谢。

共有1个答案

屠昌胤
2023-03-14

此片段是否创建3个线程?

你的程序创建了五个线程。每个线程负责显示的五行输出中的一行。

我认为将打印的线程名称将是demo2.1、t1、t2,因为我在构造函数中传递了这些名称。

这五个线程分别命名为“demo2.1”、“t1”、“t2”、“tR1”和“tR2”,但“t1”和“t2”线程永远不会打印自己的名称。那是因为您为它们中的每一个都提供了一个Runnable委托,它恰好是“demo2.1”线程实例。

demo2.1实例的run()方法(Demo2类的run()方法)打印自己的名称,这并不总是运行它的线程的名称。

更详细地说:

在这里,您创建了一个新对象,它是一个Demo2,它是一个线程,并且实现了它

Demo2 objT1 = new Demo2("demo2.1")

当你调用objT1时。start(),新线程调用Demo2。运行()。getName()

好吧,这很简单,但下一步就不那么简单了。

在这里,您创建了另一个新对象,它是一个线程,使用前面的objT1作为其Runnable委托,名为“t1”:

Thread tT1 = new Thread(objT1,"t1");

当你调用tT1.start()时,新线程将调用它的委托的run()方法。它将调用Demo2.run()。但是回想一下,Demo2是一个带有名称的Thread,它的run方法打印自己的名称(实际上是this.getName()),而不是打印正在运行它的线程的名称(这将是Thread.currentThread(). getName())。

回顾:

您正在以两种不同的方式使用objT1

  1. 您可以将其用作线程

这三次,它都打印自己的名称,这与在使用对象作为线程委托的两种情况下运行它的线程的名称不同。

 类似资料:
  • 我正在学习多线程的基础知识,并且正在编写一个程序来理解使用两种创建线程的方法之间的区别。 我已经读到,使用Runnable允许多个线程共享同一个对象,并希望在扩展线程时尝试类似的事情。因此,在创建了Demo2的新对象之后,我将引用传递给了线程构造函数(类似于我们在Runnable中所做的)。 当objT1,tT1,tT2将总和的值增加到3时,我达到了我想要达到的目标。但是在打印当前线程的名称时,它

  • 我需要编写一个扩展Thread类的应用程序。我的类在实例化时接受一个整数(即100)<代码>(MyThread myt=新的MyThread(100);) 这个整数将是这个类循环并打印消息的次数。消息应该是“线程正在运行…100”。100将是我传入构造函数的任何数字。如果数字是150,那么输出应该是“线程正在运行…100”。我应该使用main方法来测试这个类。在主线程中,我将启动两个线程,一个线程

  • 背景:我正在并行运行自动化测试。使用pom.xml中的分叉,多个浏览器在相同数量的线程中启动,即1个浏览器是1个线程。 中的下面插件创建了与线程(fork)计数相等数量的。 所有这些类都同时并行执行。因此,似乎每当我创建或时,每个线程都会创建自己的这些,因此跨多个线程共享变量的概念是不起作用的。 我只想让一个线程访问“准备测试数据”函数,并将<code>标志 我正在按照教程https://www.

  • 我创建了一个可运行的类a,它为我执行一些任务。我使用ExecutorService提交这个类,以便并行执行这些任务。 可运行类A调用另一个对象B,该对象发送一个AsyncFuture请求(future.get()one)。 我将可运行类A的单独对象提交给ExecutorService,但是,类B的对象由bean(单例)引用。这会导致线程执行出现问题吗? 我注意到类A的一些对象没有被任何线程执行。

  • 现在我的问题是:关键字对这种情况有用吗?

  • 我已经面临这个问题很多天了,请帮我解决。我正在使用线程同步实现生产者-消费者示例。我在这个传统节目中做了一些调整。我没有只使用一个队列对象,而是使用了两个队列对象。但程序不起作用。。(PS-我知道我可以通过只使用队列的一个对象来让这个程序工作,但如果我想使用两个队列对象呢??) 类队列{ } 类生产者实现Runnable{ } 类消费者实现可运行{ } 公共类测试队列{ }