2、线程的创建
来源:互联网 发布:淘宝开学季什么时候 编辑:程序博客网 时间:2024/06/09 19:19
线程的创建
Java 提供了三种创建线程的方法:
- 通过实现 Runnable 接口;
- 通过继承 Thread 类本身;
- 通过 Callable 和 Future 创建线程。
我们将使用第二种方法来制作一个简单的程序,它能创建和运行10个线程。每一个线程能计算和输出1-10以内的乘法表。
通过实现 Runnable 接口来创建线程
创建一个名为Calculator的类,这个类要实现Runnable接口。
package com.lf.base.creat;/** * Created by LF on 2017/5/10. */public class Calculator implements Runnable { private int number; public Calculator(int number) { this.number = number; } @Override public void run() { for (int i = 1; i <= 10; i++) { System.out.printf("%s: %d * %d = %d\n", Thread.currentThread().getName(), number, i, i * number); } }}
重写该方法,重要的是理解的 run() 可以调用其他方法,使用其他类,并声明变量,就像主线程一样。
在创建一个实现 Runnable 接口的类之后,你可以在类中实例化一个线程对象。
通过继承Thread来创建线程
创建一个线程的第二种方法是创建一个新的类,该类继承 Thread 类,然后创建一个该类的实例。
继承类必须重写 run() 方法,该方法是新线程的入口点。它也必须调用 start() 方法才能执行。
该方法尽管被列为一种多线程实现方式,但是本质上也是实现了 Runnable 接口的一个实例。
public class MyThread extends Thread { private int number; public MyThread(int number) { this.number = number; } @Override public void run() { for (int i = 1; i <= 10; i++) { System.out.printf("%s: %d * %d = %d\n", Thread.currentThread().getName(), number, i, i * number); } }}
通过 Callable 和 Future 创建线程
- 创建 Callable 接口的实现类,并实现 call() 方法,该 call() 方法将作为线程执行体,并且有返回值。
- 创建 Callable 实现类的实例,使用 FutureTask 类来包装 Callable 对象,该 FutureTask 对象封装了该 Callable 对象的 call() 方法的返回值。
- 使用 FutureTask 对象作为 Thread 对象的 target 创建并启动新线程。
- 调用 FutureTask 对象的 get() 方法来获得子线程执行结束后的返回值。
public class MyCallable implements Callable<Integer> { public static void main(String[] args) { FutureTask<Integer> futureTask = new FutureTask<>(new MyCallable()); for (int i = 0; i < 100; i++) { System.out.println(Thread.currentThread().getName() + " 的循环变量i的值" + i); if (i == 20) { new Thread(futureTask, "有返回值的线程").start(); } } } @Override public Integer call() throws Exception { int i = 0; int size = 100; for (; i < size; i++) { System.out.println(Thread.currentThread().getName() + " " + i); } return i; }}
每个Java程序最少有一个执行线程。当你运行程序的时候, JVM运行负责调用main()方法的执行线程。
当调用Thread对象的start()方法时, 我们创建了另一个执行线程。在这些start()方法调出后,我们的程序就有了多个执行线程。
当全部的线程执行结束时(更具体点,所有非守护线程结束时),Java程序就结束了。如果初始线程(执行main()方法的主线程)运行结束,其他的线程还是会继续执行直到执行完成。但是如果某个线程调用System.exit()指示终结程序,那么全部的线程都会结束执行。
创建一个Thread类的对象不会创建新的执行线程。同样,调用实现Runnable接口的 run()方法也不会创建一个新的执行线程。只有调用start()方法才能创建一个新的执行线程。
线程的属性
Thread类的对象中保存了一些属性信息能够帮助我们来辨别每一个线程,知道它的状态,调整控制其优先级。 这些属性是:
- ID: 每个线程的独特标识。
- Name: 线程的名称。
- Priority: 线程对象的优先级。优先级别在1-10之间,1是最低级,10是最高级。不建议改变它们的优先级,但是你想的话也是可以的。
- Status: 线程的状态。在Java中,线程只能有这6种中的一种状态: new, runnable, blocked, waiting, time waiting, 或 terminated.
Thread 类有能保存使用线程信息的属性。JVM根据线程的优先级来选择将使用CPU的线程,然后再根据每个线程的情况来实现它们的状态。
如果你没有声明一个线程的名字,那么JVM会自动命名它为:Thread-XX,XX是一个数字。线程的ID或者状态是不可修改的。Thread类没有实现setId()和setStatus()方法来允许修改它们。
你可以用Thread类的静态方法currentThread()来访问正在运行的Runnable 对象的 Thread对象。
Thread和Runnable的异同点
Thread 和 Runnable 的相同点:都是“多线程的实现方式”。
Thread 和 Runnable 的不同点:
- Thread 是类,而Runnable是接口;
- Thread本身是实现了Runnable接口的类。我们知道“一个类只能有一个父类,但是却能实现多个接口”,因此Runnable具有更好的扩展性。
此外,Runnable还可以用于“资源的共享”。即,多个线程都是基于某一个Runnable对象建立的,它们会共享Runnable对象上的资源。
通常,建议通过“Runnable”实现多线程!
start() 和 run()的区别说明
start() : 它的作用是启动一个新线程,新线程会执行相应的run()方法。start()不能被重复调用。
run() : run()就和普通的成员方法一样,可以被重复调用。单独调用run()的话,会在当前线程中执行run(),而并不会启动新线程!
- 线程的创建-2
- 2、线程的创建
- 创建线程的方法2
- 线程之线程的创建
- java线程技术2_线程的创建运行终止
- java线程技术2_线程的创建运行终止
- 如何正确的创建线程,终了线程(2)
- JAVA 创建线程的2种方法
- Java多线程2—线程的创建
- Java多线程2—线程的创建
- 内核线程的创建(2)
- 多线程篇2 线程的创建
- Java--线程的创建方式(2)
- 线程的创建方式(2+1)
- 线程的2种简单创建
- java创建线程的2种方式
- 创建线程的2种方式
- Java 创建线程的方法2
- Codeforces Round #452 (Div. 2)
- java网络编程方面笔记
- linux查看文件
- linux学习笔记9
- ubuntu-16.04安装mongodb
- 2、线程的创建
- mysql忘记root账户密码时的登录方式以及修改root密码
- C++温故而知新----2
- 3、线程的调度
- python-数据分析
- IT行业风投
- CSS中强大的属性选择器
- python常见安装命令
- redis-安装和简单配置