该方法将咱们本身定义的一个线程类继承自Thread类,并重写run()方法来重定义该线程所进行的操做。
线程类:java
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); } } }
结果:ide
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
咱们自定义的线程和主线程交替凌乱地执行。函数
线程类:测试
public class Thread2 implements Runnable { // 重写run方法重定义线程执行的内容 @Override public void run() { for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName() + "执行" + i); } } }
测试类:this
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
实质上匿名内部类的方法就是实现Runnable接口,只不过这个类没有名字。
测试类:code
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
主要的区别有亮点:
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接口的方法能够是的多个线程共享同一个资源变得可能,所以在资源共享性上更胜一筹。