我是多线程的新手,在练习时我编写了以下代码。我想调用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
答案 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());