一、进程:多线程
进程是程序的一次动态执行过程。用进程来对应一个程序,每一个进程对应必定的内存地址空间,而且只能使用它本身的内存空间,各个进程间互不干扰。ide
二、线程:测试
线程是程序内部的控制流,比进程更小的执行单位,是进程内部的子任务。一个进程在执行过程当中,为了同时完成多个操做,能够产生多个线程,造成多条执行线索。ui
三、进程与线程的区别:spa
(1)、每一个进程有一段专有内存空间。进程各自占有不一样空间,内存消耗很大,会形成系统在不一样程序之间切换时开销很大,进程之间通讯速度很慢。.net
(2)、同一进程的各线程之间共享相同内存空间,利用共享内存来实现数据交换、实时通讯及必要的同步工做。线程之间通讯速度快,相互切换所占系统资源也小。线程
在Java中,线程的建立通常有2种方式:1.继承Thread类 ;2.实现Runnable接口。对象
示例代码:blog
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
package
com.model.elgin.thread; public class TestThread1 { public static void main( String [] args) { MyThread mt1= new MyThread(); MyThread mt2= new MyThread(); //setName方法为线程命名 mt1.setName( "mt1" ); mt2.setName( "mt2" );; //start方法开启线程 mt1.start(); mt2.start(); } } class MyThread extends Thread{ @Override public void run() { for ( int i = 0 ; i < 10 ; i++) { //currentThread()为Thread类的静态方法,做用是获得当前正在运行的线程 System.out.println(Thread.currentThread().getName() + ": Hello thread-" + i); } } } |
运行结果:继承
从上面的运行结果能够看出:2个线程在同时运行,争夺CPU资源,并无前后的优先级,若是再次运行一次,那么会获得不一样的顺序结果。
示例代码:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
package
com.model.elgin.thread; public class TestThread2 { public static void main( String [] args) { //声明一个资源类实例 RunThread rt= new RunThread(); //将此实例传入Thread构造方法,建立线程对象 Thread rmt1= new Thread(rt); rmt1.setName( "rmt1" ); Thread rmt2= new Thread(rt); rmt2.setName( "rmt2" ); rmt1.start(); rmt2.start(); } } //声明资源类,须要实现Runnable接口,用来建立线程 class RunThread implements Runnable{ @Override public void run() { for ( int i = 0 ; i < 10 ; i++) { //currentThread()为Thread类的静态方法,做用是获得当前正在运行的线程 System.out.println(Thread.currentThread().getName() + ": Hello thread-" + i); } } } |
注意,这种方式必须将Runnable做为Thread类的参数,而后经过Thread的start方法来建立一个新线程来执行该子任务。
若是直接调用Runnable的run方法的话,是不会建立新线程的,这跟普通的方法调用没有任何区别。
事实上,查看Thread类的实现源代码会发现Thread类是实现了Runnable接口的。
小结:
在Java中是不支持多继承的,若是一个类已经继承了另外一个类,那么它就不能经过继承Thread类来实现多线程操做,这时候就可使用第二种方式,也就是实现Runable接口来实现。由于Java是单继承,多实现的。另外一个方面说,若是一个类已经继承Thread了,那么它就没法继承其余类去实现更复杂的功能,因此多线程的实现推荐使用实现Runable接口的方式。
#上面2个例子中已使用过
public static native Thread currentThread() 返回当前活动线程的引用;
public static native void yield() 使当前执行线程暂时中止执行而让其余线程执行;
示例:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
package
com.model.elgin.thread; public class TestThread1 { public static void main( String [] args) { MyThread mt1= new MyThread(); MyThread1 mt2= new MyThread1(); //setName方法为线程命名 mt1.setName( "mt1" ); mt2.setName( "mt2" );; //start方法开启线程 mt1.start(); mt2.start(); } } class MyThread extends Thread{ @Override public void run() { for ( int i = 0 ; i < 10 ; i++) { //currentThread()为Thread类的静态方法,做用是获得当前正在运行的线程 System.out.println(Thread.currentThread().getName() + ": Hello thread1-" + i); } } } class MyThread1 extends Thread{ @Override public void run() { //调用yield方法使当前线程暂停等其它线程执行完毕以后再执行它 //Thread.yield(); for ( int i = 0 ; i < 10 ; i++) { //currentThread()为Thread类的静态方法,做用是获得当前正在运行的线程 System.out.println(Thread.currentThread().getName() + ": Hello thread2-" + i); } } } |
结果对比:
左边为未打开34行注释的结果(即未调用yield方法),右边是调用yield的结果
public static native void sleep(long millis) throws InterruptedException 使当前活动线程睡眠指定的时间millisme;
public static void sleep(long millis,int nanos)throws InterruptedException 使当前活动线程睡眠指定的时间millisme加上十万分之nanos秒;
public native synchronized void start() 开始运行当前线程;
public void run() 该方法用来定义线程体。一旦线程被启动执行,就开始执行这个方法;
public final native boolean isAlive() 测试当前线程是否在活动;
#---------@Deprecated注解方法开始,不鼓励使用-----------#
public final void stop() 强制当前线程中止运行,并抛出ThreadDead错误;
public void destroy() 撤消当前线程;
public final void suspend() 临时挂起当前线程;
public final void resume() 恢复运行挂起的线程;
#---------@Deprecated注解方法结束,不鼓励使用-----------#
public final void setPriority(int newPriouity) 设置线程的优先级
能够在MIN_PRIORITY、NORM_PRIORIITY和MAX_PRIORITY之间,通常MIN_PRIORITY为1,MAX_PRIORITY为10;
public final int getPriority() 得到当前线程的优先级;
public final void setName(String name) 设置线程名;
public final String getName() 获得当前线程名;
public final ThreadGroup getThreadGroup( ) 返回当前的线程组;
小结:
Thread提供的控制线程的主要方法:
后续将结合线程的生命周期来介绍上述的几个重点方法