java线程的基础实例解析
java中建立线程可以有两种方式,分别是继承Thread类和实现Runnable接口。 继承Thread public class MyThread extends Thread{ public MyThread(String name){ super(name); } int i; public void run(){ for(i=0;i<5;i++){ System.out.println(getName()+"--"+i); } } public static void main(String[] agrs){ new MyThread("线程1").start(); new MyThread("线程2").start(); } } /* 线程1--0 线程1--1 线程1--2 线程1--3 线程1--4 线程2--0 线程2--1 线程2--2 线程2--3 线程2--4 */ 如上,java中的线程对象必须一个类的形式创建,而该类中必须重写基类的run()方法,该方法其实就是线程的执行体。调用该类实例的start方法则就隐式的调用了run方法。 不难看出,由于new了2次MyThread,所以两次的实例是不同的,即各自都有各自的i变量,相互独立。 Runnable接口 public class MyRunnable implements Runnable{ int i; public void run(){ for(i=0;i<50;i++){ System.out.println(Thread.currentThread().getName()+"--"+i);//不能直接this.getName() } } public static void main(String[] agrs){ MyRunnable myRun=new MyRunnable(); new Thread(myRun,"线程1").start(); new Thread(myRun,"线程2").start(); } } /* 线程1--0 线程1--1 线程2--0 线程2--3 线程2--4 线程2--5 线程2--6 线程2--7 线程2--8 线程2--9 线程2--10 线程2--11 线程2--12 线程2--13 线程2--14 线程2--15 线程1--2 线程2--16 线程2--18 线程2--19 线程2--20 线程2--21 线程2--22 线程2--23 线程2--24 线程1--17 线程2--25 线程1--26 线程2--27 线程1--28 线程1--30 线程2--29 线程1--31 线程2--32 线程2--34 线程2--35 线程2--36 线程2--37 线程1--33 线程2--38 线程1--39 线程1--41 线程2--40 线程1--42 线程1--44 线程1--45 线程2--43 线程1--46 线程2--47 线程2--49 线程1--48 */ 可以看出,由于实现这种方式是将某一个对象做为target加载到Thread类上,所以即使new再多的Thread对象,只要target是同一引用的对象,则就调用该对象的run方法,所有线程均共享该target对象的资源,所以会看到线程1和线程2一共输出了51次,2条线程共同完成了i从0到49的输出,而并不像上面那样分别输出5次。至于为什么输出了51条,两条线程几乎在同一时刻进入就绪状态(start方法只是让线程进入就绪状态),观察上面的i变量不难发现当i等于0时,此时线程1和线程2均同时处于运行状态,产生了并发现象,共同输出了i=0,而此之后CPU通过不断的切换线程,使得在同一时刻只有一条线程在输出。 线程状态 线程分为4个状态 就绪状态:调用start方法则进入就绪状态。 线程的基本操作 join()合并线程:当前线程调用某线程的join方法后将会等待某线程执行完毕后本线程才会继续。 后台线程 一个程序被操作系统执行后将有一个进程,一个进程至少有一个线程(主线程),主线程并没有比其他线程有太多的特殊之处,只因为它是最早被执行的线程,在主线程中将会创建其他线程,若不指明则默认创建的是前台线程(包括main线程),若调用setDaemon(true)则显式的将该线程设置为后台线程,后台线程为Daemon线程,从名字就能看出,它的主要作用是为其他线程提供守护,服务的功能。当所有前台线程结束后,后台线程将会被强制结束,因为它此时已经没有存在的意义了。 前台线程 public class ForeAndBackThread extends Thread{ public ForeAndBackThread(String name){ super(name); } public void run(){ int i; for(i=0;i<9999;i++){ System.out.println(this.getName()+"--"+i); } } public static void main(String[] args){ ForeAndBackThread th=new ForeAndBackThread("线程A"); //th.setDaemon(true); th.start(); int j; for(j=0;j<3;j++){ System.out.println(Thread.currentThread().getName()+"--"+j); } } } 程序完整的输出子线程中0到9998;说明主线程并没有什么特殊的,它的结束并不会影响其他前台线程的运行。 后台线程 public class ForeAndBackThread extends Thread{ public ForeAndBackThread(String name){ super(name); } public void run(){ int i; for(i=0;i<9999;i++){ System.out.println(this.getName()+"--"+i); } } public static void main(String[] args){ ForeAndBackThread th=new ForeAndBackThread("线程A"); th.setDaemon(true); th.start(); int j; for(j=0;j<3;j++){ System.out.println(Thread.currentThread().getName()+"--"+j); } } } 程序并不能完整的输出0-9998就退出了,说明前台主线程结束后,jvm强制结束了后台线程。 总结 以上就是本文关于java线程的基础实例解析的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |