在java中有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口;
1》Thread类是在java.lang包中定义的。一个类只要继承了Thread类同时覆写了本类中的run()方法就可以实现多线程操作了,但是一个类只能继承一个父类,这是此方法的局限。
package com.test.thread; public class ThreadTest extends Thread { private String name; public ThreadTest() { // TODO Auto-generated constructor stub } public ThreadTest(String name){ this.name=name; } @Override public void run() { // TODO Auto-generated method stub super.run(); for(int i=0;i<20;i++){ System.out.println(this.name+"run()--"+i); } } }
package com.test.thread; public class Test { public static void main(String[] args) { // TODO Auto-generated method stub ThreadTest ttA = new ThreadTest("Thread A"); ttA.run(); ThreadTest ttB = new ThreadTest("Thread B"); ttB.run(); } }
Thread Arun()--20 Thread Arun()--19 Thread Arun()--18 Thread Arun()--17 Thread Arun()--16 Thread Arun()--15 Thread Arun()--14 Thread Arun()--13 Thread Arun()--12 Thread Arun()--11 Thread Arun()--10 Thread Arun()--9 Thread Arun()--8 Thread Arun()--7 Thread Arun()--6 Thread Arun()--5 Thread Arun()--4 Thread Arun()--3 Thread Arun()--2 Thread Arun()--1 Thread Brun()--20 Thread Brun()--19 Thread Brun()--18 Thread Brun()--17 Thread Brun()--16 Thread Brun()--15 Thread Brun()--14 Thread Brun()--13 Thread Brun()--12 Thread Brun()--11 Thread Brun()--10 Thread Brun()--9 Thread Brun()--8 Thread Brun()--7 Thread Brun()--6 Thread Brun()--5 Thread Brun()--4 Thread Brun()--3 Thread Brun()--2 Thread Brun()--1
但是,此时结果很有规律,先第一个对象执行,然后第二个对象执行,并没有相互运行。在JDK的文档中可以发现,一旦调用start()方法,则会通过JVM找到run()方法。下面启动start()方法启动线程:
package com.test.thread; public class Test { public static void main(String[] args) { // TODO Auto-generated method stub ThreadTest ttA = new ThreadTest("Thread A"); //ttA.run(); ttA.start(); ThreadTest ttB = new ThreadTest("Thread B"); //ttB.run(); ttB.start(); } }测试结果:
Thread Arun()--20 Thread Arun()--19 Thread Arun()--18 Thread Arun()--17 Thread Arun()--16 Thread Arun()--15 Thread Arun()--14 Thread Arun()--13 Thread Arun()--12 Thread Arun()--11 Thread Brun()--20 Thread Arun()--10 Thread Brun()--19 Thread Arun()--9 Thread Arun()--8 Thread Arun()--7 Thread Arun()--6 Thread Brun()--18 Thread Arun()--5 Thread Brun()--17 Thread Arun()--4 Thread Brun()--16 Thread Arun()--3 Thread Brun()--15 Thread Brun()--14 Thread Brun()--13 Thread Arun()--2 Thread Brun()--12 Thread Arun()--1 Thread Brun()--11 Thread Brun()--10 Thread Brun()--9 Thread Brun()--8 Thread Brun()--7 Thread Brun()--6 Thread Brun()--5 Thread Brun()--4 Thread Brun()--3 Thread Brun()--2 Thread Brun()--1
这样程序可以正常完成交互式运行。那么为啥非要使用start()方法启动多线程呢?
在JDK的安装路径下,src.zip是全部的java源程序,通过此代码找到Thread中的start()方法的定义,可以发现此方法中使用了private native void start0();其中native关键字表示可以调用操作系统的底层函数,那么这样的技术成为JNI技术(java Native Interface)
2》
Runnable接口
在实际开发中一个多线程的操作很少使用Thread类,而是通过Runnable接口完成。
package com.test.thread; public class ThreadTest2 implements Runnable { private String name; int count = 20; public ThreadTest2() { // TODO Auto-generated constructor stub } public ThreadTest2(String name) { this.name = name; } @Override public void run() { // TODO Auto-generated method stub for (int i = 0; i < 20; i++) { if (this.count > 0) System.out.println(this.name + "run()--" + count--); } } }
package com.test.thread; public class Test { public static void main(String[] args) { // TODO Auto-generated method stub // ThreadTest ttA = new ThreadTest("Thread A"); // //ttA.run(); // ttA.start(); // ThreadTest ttB = new ThreadTest("Thread B"); // //ttB.run(); // ttB.start(); ThreadTest2 ttA=new ThreadTest2("Thread A"); new Thread(ttA).start(); ThreadTest2 ttB=new ThreadTest2("Thread B"); new Thread(ttB).start(); } }
Thread Brun()--20 Thread Brun()--19 Thread Brun()--18 Thread Brun()--17 Thread Arun()--20 Thread Brun()--16 Thread Brun()--15 Thread Brun()--14 Thread Arun()--19 Thread Arun()--18 Thread Brun()--13 Thread Brun()--12 Thread Brun()--11 Thread Arun()--17 Thread Brun()--10 Thread Arun()--16 Thread Arun()--15 Thread Brun()--9 Thread Brun()--8 Thread Brun()--7 Thread Brun()--6 Thread Brun()--5 Thread Brun()--4 Thread Brun()--3 Thread Arun()--14 Thread Arun()--13 Thread Arun()--12 Thread Arun()--11 Thread Arun()--10 Thread Arun()--9 Thread Brun()--2 Thread Brun()--1 Thread Arun()--8 Thread Arun()--7 Thread Arun()--6 Thread Arun()--5 Thread Arun()--4 Thread Arun()--3 Thread Arun()--2 Thread Arun()--1
还是利用上述代码,只不过测试代码为:
package com.test.thread; public class Test { public static void main(String[] args) { // TODO Auto-generated method stub // ThreadTest ttA = new ThreadTest("Thread A"); // //ttA.run(); // ttA.start(); // ThreadTest ttB = new ThreadTest("Thread B"); // //ttB.run(); // ttB.start(); ThreadTest2 ttA = new ThreadTest2("Thread A"); // 同一个ttA可以,但是通过继承Thread类却不可以,如果用同一个实例化对象就会出现异常 new Thread(ttA).start(); new Thread(ttA).start(); new Thread(ttA).start(); } }测试结果:
Thread Arun()--19 Thread Arun()--17 Thread Arun()--16 Thread Arun()--15 Thread Arun()--14 Thread Arun()--18 Thread Arun()--20 Thread Arun()--12 Thread Arun()--13 Thread Arun()--9 Thread Arun()--8 Thread Arun()--10 Thread Arun()--6 Thread Arun()--5 Thread Arun()--11 Thread Arun()--3 Thread Arun()--4 Thread Arun()--7 Thread Arun()--1 Thread Arun()--2虽然现在程序中有三个线程,但是一共卖了20张票,也就是说使用Runnable实现多线程可以达到资源共享目的。