为了提升对某一任务或某一问题的解决速度,或者说程序设计管理,我们需要使用并发。
Java的并发编程基于Java语言提供的两种基本的语法规则:
1.使用或扩展java.lang.Thread类,创建线程
2.实现java.lang.Runnable接口
Thread类的使用
Thread主要有两个重要的方法
(1)start() (2)run()
一个任务的工作流程是写在run()方法中,线程在实际的运行过程中也是以来run方法去进行任务执行。
通过一个例子来具体说明Thread的运作过程:
我们定义一个TesterThread,在run方法和start方法中加入显示的输出。
1 package com.sample; 2 public class TesterThread extends Thread{ 3 @Override 4 public void run() { 5 System.out.println("Calling Thread run() Method"); 6 } 7 8 @Override 9 public synchronized void start() {10 // TODO Auto-generated method stub11 super.start();12 System.out.println("Calling Thread start() Method");13 }14 }
测试这个线程
1 package com.sample; 2 3 public class MainTester { 4 public static void main(String[] args) { 5 TesterThread tThread = new TesterThread(); 6 tThread.start(); 7 tThread.run(); 8 9 }10 11 }
可能会产生以下两种输出
(1)
(2)
好了,下面就通过这两个输出来说明Thread的具体运作方式。
当我们在主线程mian里面new出一个新的thread的时候,它并没有捕获任何对这个对象的引用。但是在使用thread的时候就不同了,每个thread都注册了自己,这时候,就确实有一个对它自己的引用,而且在他的任务退出其run()并死亡之前,GC无法回收它。因此,我们可以这样理解一个线程会创建一个单独的执行线程,,在对start()调用完成后,他仍旧会继续存在。调用线程的start(),是一个复杂的过程,首先启动线程,然后进行线程的状态转移,当转移到可运行状态时,当线程获得执行时间片后,完成run()方法的执行。当然run()方法跟普通的java方法没有任何去别,所以直接调用是可以的,当然请不要把thread.run()的调用误解成是线程的执行,他就是一个类的方法调用而已。所以我们就可以解释上面出现的两种输出结果。对于第一个输出,虽然主线程调用用户线程的start()但是由于线程切换的各种可能因素的共同作用,tThread没有第一时间获得执行,所以,主线程会直接调用tThread的run方法予以执行。对于第二个输入,第一时间切换完成,所以会有相应的输出。
Runnable接口的使用
使用Runnable接口,来实现线程,依旧需要使用Thread,常用的Thread构造函数如下:
Thread(Runnable target)
Thread(Runnable target, String name) Thread(ThreadGroup group, Runnable target) Thread(ThreadGroup group, Runnable target, String name) Thread(ThreadGroup group, Runnable target, String name, long stackSize)一个代码示例:
1 package com.sample;2 3 public class TesterRunnable implements Runnable {4 @Override5 public void run() {6 System.out.println("Calling Runnable run() Method");7 }8 }
1 package com.sample;2 3 public class MainTester {4 public static void main(String[] args) {5 TesterRunnable tRunnable = new TesterRunnable();6 Thread tRunThread = new Thread(tRunnable);7 tRunThread.run();8 }9 }
在Java中,对于一个线程来说,有自己的方法栈,方法栈是线程私有的,没一个线程都拥有一个私有的方法栈,在调用到start方法的时候,jvm最终会执行一个叫做start0()的本地方法,java叫做native method,这个方法也就是最终映射在操作系统的线程里,进行执行的方法。在线程切换的时候,也是在栈间进行切换。