首先,在java中主要由两种方式创建线程
方式1:继承Thread,然后重写run方法,最后调用start启动线程
Thread thread1 = new Thread() {
@Override
public void run() {
while(true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("currentThread thread: " + Thread.currentThread().getName());
}
}
};
thread1.start();方式2:继承Runnable接口,然后传给Thread对象,最后调用starg启动线程
Thread thread2 = new Thread(new Runnable() {
public void run() {
while(true) {
System.out.println("1");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("currentThread thread: " + Thread.currentThread().getName());
}
}
}
).start();
public void run() {
if (target != null) {
target.run();
}
}而这个target是Thread类中的一个Runnable对象 /* What will be run. */
private Runnable target;然后再构造时如果有传入Runnable对象则会调用init方法对target进行赋值
public Thread(Runnable target) {
init(null, target, "Thread-" + nextThreadNum(), 0);
}所以当有传入Runnable方法时的Thread,在调用start时会调用Runnable中的run方法。
但大部分的写法都是采用第二种写法,因为第二种写法的思路很清晰:构造一个线程,然后这个传入一个线程的执行方法,而这个方法便是Runnable的run方法,就像pthread中的回调函数一样,更符合面向对象的过程。
当然根据多态,如果既传入了Runnable又重写了run方法的Thread的子类,是肯定会调用子类重写的run方法。
Thread thread2 = new Thread(new Runnable() {
public void run() {
while(true) {
System.out.println("1");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("currentThread thread: " + Thread.currentThread().getName());
}
}
}
){
@Override
public void run() {
System.out.println("2");
while(true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("currentThread thread: " + Thread.currentThread().getName());
System.out.println("this thread: " + this.getName());
}
}
};
thread2.start();控制台肯定只会先打印2
2
currentThread thread: Thread-1
this thread: Thread-1
本文介绍了Java中创建线程的两种常见方式:继承Thread类并重写run方法,或者实现Runnable接口并将其传递给Thread对象。文章通过示例代码详细解释了这两种方式的工作原理,并讨论了它们之间的差异。

被折叠的 条评论
为什么被折叠?



