一个对象可以在Java中创建多个线程

时间:2014-04-17 14:06:31

标签: java multithreading concurrency

我是多线程的新手,在练习时我编写了以下代码。我想调用createThred方法创建一个我称之为的新线程evrytime。但是,使用下面给出的代码,每次调用createThread方法时,我都会反复运行相同的线程。是否可以使用同一对象创建新线程?显然不是,只是想确认是否有一种我不知道的方式。

public class ThreadStartRunnable implements Runnable {

    private Thread t;
    /*
     ThreadStartRunnable(String name) {
         t = new Thread(this, name);
        t.start();
        }
     */
       private Thread createThread(String name){

         t = new Thread(this,name);
         t.start();
         return t;
     }

    /**
     * @Override run
     * 
     */
    public void run() {

        for(int i=0;i<=5;i++)
        {
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println("The current Thread is " + t.getName() + " and thread ID is " + t.getId());
        }
    }
    /**
     * @param args
     * @throws InterruptedException 
     */
    public static void main(String[] args)  {
        // TODO Auto-generated method stub

        Thread t = Thread.currentThread();
        //new ThreadStartRunnable("User 1");
        //new ThreadStartRunnable("User 2");
        //ThreadStartRunnable c = new ThreadStartRunnable();
        ThreadStartRunnable t1 = new ThreadStartRunnable();

        t1.createThread("Child 1");
        t1.createThread("Child 2");

        for(int i=0;i<=5;i++)
        {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println("The cirrent Thread is " + t.getName()+ " and thread ID is " + t.getId());
        }




    }

}
  

输出:

     

当前线程是子级2,线程ID是9

     

当前线程是子级2,线程ID是9

     

循环线程为主线程,线程ID为1

     

当前线程是子级2,线程ID是9

     

当前线程是子级2,线程ID是9

     

当前线程是子级2,线程ID是9

     

当前线程是子级2,线程ID是9

     

当前线程是子级2,线程ID是9

     

当前线程是子级2,线程ID是9

     

循环线程为主线程,线程ID为1

     

当前线程是子级2,线程ID是9

     

当前线程是子级2,线程ID是9

     

当前线程是子级2,线程ID是9

     

当前线程是子级2,线程ID是9

     

循环线程为主线程,线程ID为1

     

循环线程为主线程,线程ID为1

     

循环线程为主线程,线程ID为1

     

循环线程为主线程,线程ID为1

4 个答案:

答案 0 :(得分:3)

它始终显示Child 2的原因是因为您正在打印Thread t成员的名称,这是最后创建的线程。

替换:

System.out.println("The current Thread is " + t.getName() + " and thread ID is " + t.getId());

System.out.println("The current Thread is " + Thread.currentThread().getName() + " and thread ID is " + Thread.currentThread().getId());

否则可以使用相同的runnable: Initializing two threads with the same instance of a runnable

答案 1 :(得分:2)

将run code中的代码更改为显示当前线程的名称:

System.out.println("The current Thread is " + Thread.currentThread().getName() + " and thread ID is " + Thread.currentThread().getId());

每次创建新Thread时都会覆盖实例变量t,因此使用它来跟踪线程名称和ID是不安全的。

答案 2 :(得分:1)

您可能希望使用ExecutorService在单个对象中运行多个线程。

请看下面的代码:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Test1 {
    private ExecutorService threads;

    public Test1(int poolSize) {
        // Use fixed-size thread pool
        threads = Executors.newFixedThreadPool(poolSize);
    }

    public void createThread(String name) {
        threads.execute(new MyThread(name)); // Create MyThread
    }

    public class MyThread extends Thread {
        // Constructor passing thread name
        public MyThread(String name) {
            super(name);
        }

        @Override
        public void run() {
            for (int i = 0; i <= 5; i++) {
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                System.out.println("The current Thread is " + super.getName()
                        + " and thread ID is " + super.getId());
            }
        }
    }

    public static void main(String[] args) {
        Thread t = Thread.currentThread();
        Test1 t1 = new Test1(3);

        t1.createThread("Child 1");
        t1.createThread("Child 2");

        for (int i = 0; i <= 5; i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("The cirrent Thread is " + t.getName()
                    + " and thread ID is " + t.getId());
        }
    }
}

答案 3 :(得分:1)

问题是你使用单个引用this.t来存储线程,然后当你创建第二个线程时,你覆盖那个单引用,以便它现在指向第二个线程。因此,当你打印t.getName()时,它将引用第二个线程。

如果您希望代码按预期运行,请打印当前线程,而不是t,如下所示:

System.out.println("The current Thread is " + Thread.currentThread().getName() + " and thread ID is " + Thread.currentThread().getId());