Java多线程如何为?

摘要:如何创建一个线程? Java创建线程有两种方法,这里对三种方法做一个梳理,方便理解。 实现Runnable接口和run()方法 Java的接口就是一种协议,约定了想要被统一管理的类要遵循的协议。在Java中,线程是由Thread类创建和管理
如何创建一个线程? Java创建线程有两种方法,这里对三种方法做一个梳理,方便理解。 实现Runnable接口和run()方法 Java的接口就是一种协议,约定了想要被统一管理的类要遵循的协议。在Java中,线程是由Thread类创建和管理的,但线程需要执行具体的任务——也就是我们写的代码逻辑。而Runnable就是一个“任务的标准形式”: public class MyTask implements Runnable { @Override public void run() { System.out.println("线程正在运行:" + Thread.currentThread().getName()); } } public class Main { public static void main(String[] args) { Runnable task = new MyTask(); // 创建任务 Thread thread = new Thread(task); // 把任务交给线程 thread.start(); // 启动线程(调用 run()) } } Runnable的意义是:让任何类都可以被线程调用,Java线程调用的代码入口必须是run()方法。 所以用这个方法创建的对象,都需要交给Thread对象去管理,thread则会调用run()方法。 更常见的做法是使用内部匿名类: Thread thread = new Thread(new Runnable() { public void run() { System.out.println("匿名线程运行中!"); } }); thread.start(); 继承Thread来创建线程 public class MyThread extends Thread { public void run() { System.out.println("我是继承 Thread 的线程"); } } 另一个方法是继承Thread类,重写了它的run()方法。这种方法与实现Runnable接口的区别就是:实现Runnable接口是在实现一个任务,将任务交给线程管理者执行和控制,而继承Thread方法则是直接定义了这个线程管理者执行的任务。由于Java是单继承的,所以继承的方法缺点也很明显,灵活性较低。 继承Thread类的方式,如果想要执行一个任务,必须新建一个线程,执行完成后还要销毁,开销非常大;而实现Runnable接口只需要新建任务,可以做到同一个线程执行多个任务,大大减小了线程创建、销毁的资源浪费。 Thread类详解 为什么创建线程可以有两种方式,原因在于Thread本身就是实现了Runnable接口的一个类,因此它也必须实现run()方法,那么继承Thread类的子类也可以重写run()方法。 Java线程状态 Java中线程可以有如下6中状态:NEW 新创建,RUNNABLE 可运行,BLOCKED 阻塞,WAITING 等待,TIMED WAITING 计时等待,TERMINATED 终止。 在现代JVM中,Java的线程本质上就是操作系统线程(Native Thread),并且是一一对应的关系,操作系统的线程状态有五种,分别是:初始状态(NEW),可运行状态(READY),运行状态(RUNNING),等待状态(WAITING),终止状态 (TERMINATED)。 初始状态(NEW):这个状态其实是存疑的,操作系统程在调用pthread_create()后,已经在内核中被创建完成,拥有了自己的资源和调度实体,所以更类似于Java的new + start(),Java的NEW状态是指,线程在JVM层已存在,但是操作系统线程尚未分配、未创建,因此也没有占用OS资源(比如线程栈空间、线程ID)。 可运行状态(READY):线程资源已经创建,但是没有分配时间片,没有运行,对应Java的RUNNABLE可运行状态。 运行状态(RUNNING):分配时间片,正在运行,对应的也是Java的RUNNABLE可运行状态 等待状态(WAITING):对操作系统而言,等待有两个原因:被其它优先级更高的任务打断、没有获取资源。
阅读全文