Java 的“多线程”,它可以让不同的程序块一起运行,如此一来可让程序运行更为顺畅,同时也可达到多任务处理的目的
进程是程序的一次动态执行过程,它经历了从代码加载、执行到执行完毕的一个完整过程,这个过程也是进程本身从产生、发展到最终消亡的过程。每个运行中的程序就是一个进程,这一点在任务管理器上面可以形象的看到。
线程是比进程更小的执行单位,线程是进程内部单一的一个顺序控制流。比如Java的主线程main()方法 main()方法也是一个线程,实际上在命令行中运行 java 命令时,就启动了一个 JVM 的进程,默认情况下此进程会产生两个线程:一个是 main()方法线程,另外一个就是垃圾回收( GC)线程。
所谓多线程是指一个进程在执行过程中可以产生多个线程,这些线程可以同时存在、同时运行,形成多条执行线索。一个进程可能包含了多个同时执行的线程。 多线程是实现并发机制的一种有效手段。进程和线程一样,都是实现并发的一个基本单位。
1. 同样作为基本的执行单元,线程是划分得比进程更小的执行单位。 2. 每个进程都有一段专用的内存区域。与此相反,线程却共享内存单元(包括代码和数据),通过共享的内存单元来实现数据交换、实时通信与必要的同步操作。
在传统的程序语言里,运行的顺序总是必须顺着程序的流程来走,遇到 if-else 语句就加以判断,遇到 for、 while 等循环就会多绕几个圈,最后程序还是按着一定的程序走,且一次只能运行一个程序块。 Java 的“多线程”打破了这种传统的束缚。所谓的线程( Thread)是指程序的运行流程,“多线程”的机制则是指可以同时运行多个程序块,使程序运行的效率变得更高,也可克服传统程序语言所无法解决的问题。
激活线程 如果在类里要激活线程,必须先做好下面两个准备: ( 1)、线程必须扩展自 Thread 类,使自己成为它的子类。 ( 2)、线程的处理必须编写在 run()方法内。
多线程的定义语法:
class 类名称 extends Thread // 从 Thread 类扩展出子类 { 属性 方法… 修饰符 run(){ // 复写 Thread 类里的 run()方法 以线程处理的程序; } } package dd20161117; public class OtherThread extends Thread { private int tickets = 20; private boolean isGo = true; public void run() { while (isGo) { if (tickets > 0) { System.out.println(Thread.currentThread().getName() + "出售票" + tickets--); } else if (tickets == 0) { isGo = false; } } } } package dd20161117; public class ThreadDemo { public static void main(String[] args) { OtherThread otherThread=new OtherThread(); otherThread.start(); } }输出结果 Thread-0出售票20 Thread-0出售票19 … Thread-0出售票2 Thread-0出售票1
要启动线程必须调用 Thread类之中的 start()方法,而调用了 start()方法,也就是调用了 run()方法。 JAVA 程序只允许单一继承,即一个子类只能有一个父类,所以在 Java 中如果一个类继承了某一个类,同时又想采用多线程技术的时,就不能用 Thread 类产生线程,因为 Java 不允许多继承,这时就要用 Runnable接口来创建线程了。
通过实现 Runnable 接口实现多线程的定义语法:
class 类名称 implements Runnable // 实现 Runnable 接口 { 属性 方法… 修饰符 run(){ // 复写 Thread 类里的 run()方法 以线程处理的程序; } } package dd20161117; public class OtherRunnable implements Runnable { private int tickets = 20; private boolean isGo = true; public void run() { while (isGo) { synchronized (this) { if (tickets > 0) { try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "出售票" + tickets--); } else if (tickets == 0) { isGo = false; } } } } } package dd20161117; public class ThreadDemo { public static void main(String[] args) { OtherRunnable otherRunnable=new OtherRunnable(); new Thread(otherRunnable).start(); new Thread(otherRunnable).start(); new Thread(otherRunnable).start(); } }输出结果: Thread-0出售票20 Thread-0出售票19 … Thread-1出售票3 Thread-2出售票2 Thread-2出售票1 有些读者可能会不理解了,为什么实现了 Runnable 接口还需要调用Thread 类中的 start()方法才能启动多线程呢?读者通过查找 JDK 文档就可以发现,在Runnable 接口中只有一个 run()方法,在 Runnable 接口中并没有 start()方法,所以一个类实现了Runnable 接口也必须用 Thread 类中的 start()方法来启动多线程。这点可以通过查找JDK 文档中的 Thread 类发现,在 Thread 类之中,有这样一个构造方法:public Thread(Runnable target)由此构造方法可以发现,可以将一个 Runnable 接口的实例化对象作为参数去实例化 Thread 类对象。 希望读者尽可能去使用 Runnable 接口去实现多线程机制。下一文章将比较两者的区别