1.继承Thread类以创建新线程
该方法将我们自己定义的一个线程类继承自Thread类,并重写run()方法来重定义该线程所进行的操作。
线程类:
public class Thread1 extends Thread {
// 重写方法重定义该线程进行的操作
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + "执行" + i);
}
}
}
测试类:
public class Main {
public static void main(String[] args) {
// 启动线程
new Thread1().start();
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + "执行" + i);
}
}
}
结果:
main执行0
Thread-0执行0
main执行1
Thread-0执行1
main执行2
Thread-0执行2
main执行3
Thread-0执行3
main执行4
Thread-0执行4
main执行5
main执行6
main执行7
main执行8
Thread-0执行5
main执行9
Thread-0执行6
Thread-0执行7
Thread-0执行8
Thread-0执行9
我们自定义的线程和主线程交替凌乱地执行。
2.实现Runnable以创建新线程
线程类:
public class Thread2 implements Runnable {
// 重写run方法重定义线程执行的内容
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + "执行" + i);
}
}
}
测试类:
public class Main {
public static void main(String[] args) {
new Thread(new Thread2()).start();
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + "执行" + i);
}
}
}
注意这种情况的线程创建方式是将实现了Runnable接口的类填入到Thread方法的构造函数中来创建的,与第一种方法直接创建对应的继承自Thread类的子类的方式有所区别。
执行结果:
Thread-0执行0
main执行0
Thread-0执行1
main执行1
Thread-0执行2
main执行2
Thread-0执行3
main执行3
Thread-0执行4
main执行4
Thread-0执行5
main执行5
Thread-0执行6
main执行6
main执行7
Thread-0执行7
main执行8
Thread-0执行8
main执行9
Thread-0执行9
3.匿名内部类
实质上匿名内部类的方法就是实现Runnable接口,只不过这个类没有名字。
测试类:
public class Main {
public static void main(String[] args) {
// 以内部类的方式实现Runnable接口
new Thread(new Runnable() {
// 重写run方法来重定义线程执行的内容
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + "执行" + i);
}
}
}).start(); // 开启线程
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + "执行" + i);
}
}
}
执行结果:
Thread-0执行0
Thread-0执行1
Thread-0执行2
Thread-0执行3
Thread-0执行4
Thread-0执行5
Thread-0执行6
Thread-0执行7
main执行0
Thread-0执行8
main执行1
main执行2
main执行3
main执行4
main执行5
main执行6
main执行7
main执行8
main执行9
Thread-0执行9
4.继承Thread类和实现Runnable接口的区别
主要的区别有亮点:
1.因为java是单继承的机制,所以如果你选择使用继承Thread类的方式实现多线程,则无法再继承别的类实现对应的功能,而实现Runnable接口则不会有这样的问题。
2.继承Thread类不适合资源共享,而实现Runnable接口则适合实现资源共享,下面举个例子进行说明。
继承Thread类:
class MyThread extends Thread {
private int count = 15;
private String name;
public MyThread(String name) {
this.name = name;
}
@Override
public void run() {
for (int i = 0;i < 5;i++){
System.out.println(name + "执行 " + count);
count--;
}
}
}
public class Main {
public static void main(String[] args) {
new MyThread("1").start();
new MyThread("2").start();
}
}
执行结果:
1执行 15
2执行 15
2执行 14
1执行 14
2执行 13
1执行 13
2执行 12
1执行 12
2执行 11
1执行 11
实现Runnable接口:
class MyRunnable implements Runnable {
private int count = 15;
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + "执行" + count);
count--;
}
}
}
public class Main {
public static void main(String[] args) {
MyRunnable myRunnable = new MyRunnable();
// 下面两个开始的线程都来于同一个线程类,因此类中的属性可以共享
new Thread(myRunnable, "3").start();
new Thread(myRunnable, "4").start();
}
}
执行结果:
3执行15
4执行15
3执行14
3执行12
3执行11
3执行10
4执行13
4执行8
4执行7
4执行6
从执行的结果就可以看出使用实现Runnable接口的方法可以是的多个线程共享同一个资源变得可能,因此在资源共享性上更胜一筹。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。