1、继承Thread类创建线程类
通过继承Thread类来创建并启动多线程:
- 定义Thread类的子类,并重写该类的run()方法,该run()方法的方法体就是线程需要完成的任务,称为线程执行体。
- 创建Thread子类的实例,即创建了线程对象。
- 调用线程对象的start()方法来启动该线程。
package com.xtli.controller.优快云.createThread;
import java.io.IOException;
/*
* 创建线程的方式
*/
//方式1:继承Thread类
public class CreateThreadMain {
public static void main(String[] args) throws IOException {
//启动第一个线程
CreateThread my1 = new CreateThread();
my1.start();
//启动第二个线程
CreateThread my2 = new CreateThread();
my2.start();
}
}
class CreateThread extends Thread {
public void run() {
System.out.println(this.getName()+"线程启动啦");//Thread中实现了getName()方法,可以直接使用
}
}
执行结果
Thread-0线程启动啦
Thread-1线程启动啦
启动线程使用start()方法,而不是调用run()方法。直接调用run()方法,则run()方法会立即被执行,在返回结果之前,其他线程无法并发执行,即系统会把线程对象当做一个普通对象,而run()方法也是一个普通方法,而不是线程执行体。
2、实现Runnable接口
实现Runnable接口来创建并启动多线程:
- 定义Runnable接口的实现类,并重写该接口的run()方法,该run()方法的方法体同样是该线程的线程执行体。
- 创建Runnable实现类的实例,并以此实例作为Thread的target来创建Thread对象,该Thread对象才是真正的线程对象。
- Thread对象调用start()方法启动该线程
package com.xtli.controller.优快云.createThread;
import java.io.IOException;
/*
* 创建线程的方式
*/
//方式2:实现Runnable接口
public class CreateThreadSecondMain {
//不共享target实例
public static void main(String[] args) throws IOException {
//启动第一个线程
CreateThreadSecond my1 = new CreateThreadSecond();
//my1为target
new Thread(my1).start();
//启动第二个线程
CreateThreadSecond my2 = new CreateThreadSecond();
//my2为target
new Thread(my2).start();
}
}
class CreateThreadSecond implements Runnable {
private int i;
@Override
public void run() {
// TODO Auto-generated method stub
// System.out.println(this.getName()+"线程启动啦"); //不能使用this.getName()来获取当前线程名称,因为接口中只能有抽象方法和常量,不能提供getName()方法的实现
System.out.println(i++);
System.out.println(Thread.currentThread().getName()+"线程启动啦");
}
}
执行结果
0
0
Thread-0线程启动啦
Thread-1线程启动啦
两种方式中,采用Runnable接口的方式创建的多线程可以共享线程类的实例变量(上面的例子并没有共享同一个target)。因为在这种方式下,程序所创建的Runnable对象只是线程的target,而多个线程可以共享同一个target,所以多个线程可以共享同一个target类的实例变量。
实现Runnable接口时,共享同一个target,代码如下
package com.xtli.controller.优快云.createThread;
import java.io.IOException;
/*
* 创建线程的方式
*/
//方式2:实现Runnable接口
public class CreateThreadSecondMain {
/* //不共享target实例
public static void main(String[] args) throws IOException {
//启动第一个线程
CreateThreadSecond my1 = new CreateThreadSecond();
new Thread(my1).start();//my1为target
//启动第二个线程
CreateThreadSecond my2 = new CreateThreadSecond();
new Thread(my2).start();//my2为target
}*/
//共享target实例
public static void main(String[] args) throws IOException {
//启动第一个线程
CreateThreadSecond my1 = new CreateThreadSecond();
new Thread(my1).start();//my1为target
//启动第二个线程
new Thread(my1).start();//共享my1
}
}
class CreateThreadSecond implements Runnable {
private int i;
@Override
public void run() {
// TODO Auto-generated method stub
// System.out.println(this.getName()+"线程启动啦"); //不能使用this.getName()来获取当前线程名称,因为接口中只能有抽象方法和常量,不能提供getName()方法的实现
System.out.println(i++);
System.out.println(Thread.currentThread().getName()+"线程启动啦");
}
}
执行结果
0
1
Thread-0线程启动啦
Thread-1线程启动啦