package Thread;
public class main {
public static void main(String[] args) {
a a = new a();
a.start();
int i = 0;
while (true) {
System.out.println("main " + ++i + "--->" + Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (i == 5) {
break;
}
}
}
}
class a extends Thread {
@Override
public void run() {
int i = 0;
while (true) {
System.out.println("hello " + ++i + "--->" + Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (i == 10) {
break;
}
}
}
}
运行结果
java复制代码
main 1--->main
hello 1--->Thread-0
main 2--->main
hello 2--->Thread-0
hello 3--->Thread-0
main 3--->main
main 4--->main
hello 4--->Thread-0
main 5--->main
hello 5--->Thread-0
hello 6--->Thread-0
hello 7--->Thread-0
hello 8--->Thread-0
hello 9--->Thread-0
hello 10--->Thread-0
(2)如调用 run()方法,并不会启动线程,而是等 run()方法执行完之后才会启动 main 方法的调用
java复制代码
public class main {
public static void main(String[] args) {
a a = new a();
a.run();
int i = 0;
while (true) {
System.out.println("main " + ++i + "--->" + Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (i == 5) {
break;
}
}
}
}
class a extends Thread {
@Override
public void run() {
int i = 0;
while (true) {
System.out.println("hello " + ++i + "--->" + Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (i == 10) {
break;
}
}
}
}
运行结果
java复制代码
hello 1--->main
hello 2--->main
hello 3--->main
hello 4--->main
hello 5--->main
hello 6--->main
hello 7--->main
hello 8--->main
hello 9--->main
hello 10--->main
main 1--->main
main 2--->main
main 3--->main
main 4--->main
main 5--->main
结论:这里 run()方法的线程名就是 main,即调用 run()方法并没有启动线程
注意:主线程的结束并不会导致进程的结束,需要等到所有线程都执行完成进程才会退出
三、实现 Runnable 接口
引出:由于 Java 是单继承机制,如果类继承了其他类,这个时候可以通过实现接口的方式创建线程
1. 代码示例
java复制代码
package Thread;
public class main {
public static void main(String[] args) {
a a = new a();
Thread thread = new Thread(a);
thread.start();
int i = 0;
while (true) {
System.out.println("main " + ++i + "--->" + Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (i == 5) {
break;
}
}
}
}
class a implements Runnable {
@Override
public void run() {
int i = 0;
while (true) {
System.out.println("hello " + ++i + "--->" + Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (i == 10) {
break;
}
}
}
}
运行结果
java复制代码
main 1--->main
hello 1--->Thread-0
main 2--->main
hello 2--->Thread-0
hello 3--->Thread-0
main 3--->main
main 4--->main
hello 4--->Thread-0
hello 5--->Thread-0
main 5--->main
hello 6--->Thread-0
hello 7--->Thread-0
hello 8--->Thread-0
hello 9--->Thread-0
hello 10--->Thread-0
代码分析
(1)实现了 Runnable 接口,但是这个接口中并没有 start()方法,不可以直接调用
(2)通过把 a 对象作为参数传入构造器中,调用构造器创建 Thread 对象,调用 Thread 对象的 start()方法
public class main {
public static void main(String[] args) {
test test = new test();
Thread_proxy thread_proxy = new Thread_proxy(test);
thread_proxy.start();
}
}
class Thread_proxy implements Runnable{
private Runnable target = null;
// 构造器
public Thread_proxy(Runnable target) {
this.target = target;
}
// 实现 run() 方法
@Override
public void run() {
if(target != null){
target.run();
}
}
public void start(){
start0();
}
public void start0(){
run();
}
}
class test implements Runnable{
@Override
public void run() {
System.out.println("调用了 test 类的 run() 方法");
}
}
代码分析
(1)创建 Thread_proxy 类,实现 Runnable()接口,模拟 Thead 类
(2)创建 test 类,实现 Runnable()接口
(3)在主函数中创建 Thread_proxy 对象,在构造器中传入 test 对象,调用 Thread_proxy 对象的 start()方法来启动线程
底层分析
1. 为什么可以传入 test?
因为 test 是实现了 Runnable 接口的一个类,根据接口的多态,接口类型可指向实现该接口的类对象