java对多线程有着良好的支持,java创建和启动线程较为常用的方式有继承Thread类、实现Runnable接口和匿名内部类的方式。
1.继承Thread类:
通过继承Thread类来创建并启动多线程步骤如下:
1、定义Thread类的子类,并重写该类的run()方法,该run()方法的方法体就代表了线程需要完成的任务。因此把run方法称为线程执行体。
2、创建Thread子类的实例,即创建了线程对象。
3、调用线程对象的start()方法来启动该线程。
示例代码:
Thread1类(线程类):
public class Thread1 extends Thread{
@Override
public void run() {
for (int i = 0; i < 50; i++) {
System.out.println(Thread.currentThread().getName() + "执行" + i);
}
}
}
Mian类,测试类:
public class Main {
public static void main(String[] args) {
new Thread1().start();
for (int i = 0; i < 50; i++) {
System.out.println(Thread.currentThread().getName() + "执行" + i);
}
}
}
测试结果:
可以看到main线程和thread0线程的for循环交替执行,线程启动成功。此实例程序中Thread1类继承了Thread类并重写了run方法,在run方法中我们打印出当前执行的线程名称为哪个线程正在执行了,执行了多少次,使用成员变量i来记录执行的次数。在main函数中我们创建了此线程的实例对象,并通过start方法启动了这个个线程,执行时大家可以看到线程是以抢占式的方式运行。虽然只创建了1个线程实例,实际上共有2个线程在运行,还有main方法代表的主线程的线程执行体。
此外,我们还学习了线程的两个方法:
1.Thread.currentThread(),是Thread类的静态方法,该方法总是返回当前正在执行的线程对象。
2.getName():该方法是Thread类的实例方法,该方法返当前正在执行的线程的名称。在默认情况下,主线程的名称为main,用户启动的多线程的名称依次为Thread-0,Thread-1,Thread-3..Thread-n等。
2.实现Runnable接口:
实现Runnable接口创建并启动多线程的步骤如下:
1.定义Runnable接口的实现类,并重写该接口的run方法,该run方法的方法体同样是该线程的线程执行体
2.创建Runnable实现类的实例对象,并以此实例对象作为Thread的target来创建Thread类,该Thread对象才是真正的线程对象。
3.调用线程对象的start()方法来启动该线程。
示例代码:
Thread2类(线程类):
public class Thread2 implements Runnable{
public void run() {
for (int i = 0; i < 50; i++) {
System.out.println(Thread.currentThread().getName() + "执行" + i);
}
}
}
Mian类:
public class Main {
public static void main(String[] args) {
new Thread(new Thread2()).start();
for (int i = 0; i < 50; i++) {
System.out.println(Thread.currentThread().getName() + "执行" + i);
}
}
}
这里尤其是注意:main函数中名没有直接执行Thread2的run方法,而是将Thread2填入到了Thread中,使用start方法来启动。Runable实现类里包含run方法,仅仅作为线程执行体,而实际的线程对象依然是Thread实例对象,Thread为真正创建线程的对象。
3.匿名内部类:
匿名内部类本质上也是一个类实现了Runnable接口,重写了run方法,只不过这个类没有名字,直接作为参数传入Thread类,示例代码:
Main类:
public class Main {
public static void main(String[] args) {
new Thread(new Runnable() {
public void run() {
for (int i = 0; i < 50; i++) {
System.out.println(Thread.currentThread().getName() + "执行" + i);
}
}
}).start();
for (int i = 0; i < 50; i++) {
System.out.println(Thread.currentThread().getName() + "执行" + i);
}
}
}