注意:如果觉得以上内容简单可跳过本文内容,本文主要针对没怎么了解过多线程的读者
注意一下代码是死循环,程序运行后有输出应立即终止程序
public class ThreadHello { public static void main(String[] args) { //1.创建一个新线程 Thread newThread = new Thread(){ @Override public void run() { while (true) { System.out.println("hello world thread"); } } }; //2.启动该线程 newThread.start(); //3.在面线程中循环打印 while (true) { System.out.println("hello world main"); } } } 既然咱们在helloworld中都可以直接重写Thread的run方法来指定线程执行的任务,那同样的我们也可以自定义类来实现Thread重写run方法(继承方式优点:可以加入更多的任务属性,更灵活的控制线程执行任务)
如:自定义一个线程类MyThread并继承Thread类, 在run方法中打印一千次hello world
public class MyThread extends Thread { @Override public void run() { for (int i = 0; i < 1000; i++) { System.out.println("hello world"); } } } //测试自定义线程类是否生效 public static void main(String[] args) { MyThread thread = new MyThread(); thread.start(); }Thread的构造方法
public Thread() { init(null, null, "Thread-" + nextThreadNum(), 0); } public Thread(Runnable target) { init(null, target, "Thread-" + nextThreadNum(), 0); }细心的朋友应该看到了Thread的构造方法可以传入Runnable参数, 简单介绍一下Runnable是什么;
Runnable:它其实就相当于咱们之前直接使用Thread的时候的run方法,更同属的理解就是它是咱们线程去执行的任务,你在Runable的抽象run方法里面写了什么线程在执行的时候就执行什么逻辑。
实现目标:
通过传入任务(Runnable)的方式实现打印hello 100次的需求, 一下是使用的匿名内部类的方式同样也可以自己实现Runnable接口去做
public class RunnableThread { public static void main(String[] args) { Thread newThread = new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < 100; i++) { System.out.println("hello world"); } } }); newThread.start(); } } 在这里我们简单说以下为什么使用Runable: Runnable其实相当于一种策略模式, Thread在执行线程任务时把具体任务逻辑抽象出来由客户端程序员实现;其源码实现如下:
@Override public void run() { if (target != null) { target.run(); } }从中我们也可以发现只要我们传入了target就会执行target的run方法中的逻辑。
面试点1:为什么启动线程是start而不是run
相信大家如果自己写代码可能发现了run和start好像都有效果,其实不然start方法中Thread做了创建线程相关的工作, 而run方法其只是一个普通的方法。
start源代码如下:
public synchronized void start() { if (threadStatus != 0) throw new IllegalThreadStateException(); group.add(this); boolean started = false; try { // 此方法是C++实现的创建线程 start0(); started = true; } finally { try { if (!started) { group.threadStartFailed(this); } } catch (Throwable ignore) { } } }面试点2:创建线程有几种方式(目前咱们了解了两种后续还有)
通过继承Thread方法创建县城管通过实现Runable接口创建线程