Java多线程理解

来源:互联网 发布:单片机编译链接 编辑:程序博客网 时间:2024/04/27 14:31

1、多线程运行机制

  当程序运行后,您可以根据各种条件挂起或运行这些线程,尤其在多CPU的环境中,这些线程是并发运行的。多线程就是在一个进程内有多个线程。从而使一个应用程序有了多任务的功能。多进程技术也可以实现这一点,但是创建进程的高消耗(每个进程都有独立的数据和代码空间),进程之间通信的不方便(消息机制),进程切换的时间太长,这些导致了多线程的提出,对于单CPU来说(没有开启超线程),在同一时间只能执行一个线程,所以如果想实现多任务,那么就只能每个进程或线程获得一个时间片,在某个时间片内,只能一个线程执行,然后按照某种策略换其他线程执行。由于时间片很短,这样给用户的感觉是同时有好多线程在执行。 即采用多线程不会提高程序的执行速度,反而会降低速度,但是对于用户来说,可以减少用户的响应时间。


2、JavaRunnableThread的区别

java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口;Thread类是在java.lang包中定义的。一个类只要继承了Thread类同时覆写了本类中的run()方法就可以实现多线程操作了,但是一个类只能继承一个父类,这是此方法的局限。

java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口;Thread类是在java.lang包中定义的。一个类只要继承了Thread类同时覆写了本类中的run()方法就可以实现多线程操作了,但是一个类只能继承一个父类,这是此方法的局限。

下面看例子:

1.     package org.thread.demo; 

2.     class MyThread extends Thread{  

3.     private String name; 

4.     public MyThread(String name) { 

5.     super();  

6.     this.name = name; 

7.     }  

8.     public void run(){  

9.     for(int i=0;i<10;i++){  

10.   System.out.println("线程开始:"+this.name+",i="+i);  

11.   }  

12.   }  

13.   }  

14.   package org.thread.demo; 

15.   public class ThreadDemo01 { 

16.   public static void main(String[] args) { 

17.   MyThread mt1=new MyThread("线程a");  

18.   MyThread mt2=new MyThread("线程b");  

19.   mt1.run();  

20.   mt2.run();  

21.   }  

22.  

但是,此时结果很有规律,先第一个对象执行,然后第二个对象执行,并没有相互运行。在JDK的文档中可以发现,一旦调用start()方法,则会通过JVM找到run()方法。下面启动start()方法启动线程:

1.     package org.thread.demo; 

2.     public class ThreadDemo01 { 

3.     public static void main(String[] args) { 

4.     MyThread mt1=new MyThread("线程a");  

5.     MyThread mt2=new MyThread("线程b");  

6.     mt1.start();  

7.     mt2.start();  

8.     }  

9.     }; 

这样程序可以正常完成交互式运行。那么为啥非要使用start();方法启动多线程呢?

JDK的安装路径下,src.zip是全部的java源程序,通过此代码找到Thread中的start()方法的定义,可以发现此方法中使用了private nativevoid start0();其中native关键字表示可以调用操作系统的底层函数,那么这样的技术成为JNI技术(java NativeInterface

Runnable接口

在实际开发中一个多线程的操作很少使用Thread类,而是通过Runnable接口完成。

1.     public interface Runnable{  

2.     public void run();  

3.    

例子:

1.     package org.runnable.demo; 

2.     class MyThread implements Runnable{  

3.     private String name; 

4.     public MyThread(String name) { 

5.     this.name = name; 

6.     }

7.     public void run(){  

8.     for(int i=0;i<100;i++){  

9.     System.out.println("线程开始:"+this.name+",i="+i);  

10.   }  

11.   }  

12.   }; 

但是在使用Runnable定义的子类中没有start()方法,只有Thread类中才有。此时观察Thread类,有一个构造方法:publicThread(Runnable targer)此构造方法接受Runnable的子类实例,也就是说可以通过Thread类来启动Runnable实现的多线程。(start()可以协调系统的资源):

1.     package org.runnable.demo; 

2.     import org.runnable.demo.MyThread; 

3.     public class ThreadDemo01 { 

4.     public static void main(String[] args) { 

5.     MyThread mt1=new MyThread("线程a");  

6.     MyThread mt2=new MyThread("线程b");  

7.     new Thread(mt1).start(); 

8.     new Thread(mt2).start(); 

9.     }  

10.  

两种实现方式的区别和联系:

在程序开发中只要是多线程肯定永远以实现Runnable接口为主,因为实现Runnable接口相比继承Thread类有如下好处:

·        避免点继承的局限,一个类可以继承多个接口。

·        适合于资源的共享

以卖票程序为例,通过Thread类完成:

1.     package org.demo.dff; 

2.     class MyThread extends Thread{  

3.     private int ticket=10;  

4.     public void run(){  

5.     for(int i=0;i<20;i++){  

6.     if(this.ticket>0){  

7.     System.out.println("卖票:ticket"+this.ticket--);  

8.     }  

9.     }  

10.   }  

11.   }; 

下面通过三个线程对象,同时卖票:

1.     package org.demo.dff; 

2.     public class ThreadTicket { 

3.     public static void main(String[] args) { 

4.     MyThread mt1=new MyThread();  

5.     MyThread mt2=new MyThread();  

6.     MyThread mt3=new MyThread();  

7.     mt1.start();//每个线程都各卖了10张,共卖了30张票 

8.     mt2.start();//但实际只有10张票,每个线程都卖自己的票 

9.     mt3.start();//没有达到资源共享 

10.   }  

11.  

如果用Runnable就可以实现资源共享,下面看例子:

1.     package org.demo.runnable; 

2.     class MyThread implements Runnable{  

3.     private int ticket=10;  

4.     public void run(){  

5.     for(int i=0;i<20;i++){  

6.     if(this.ticket>0){  

7.     System.out.println("卖票:ticket"+this.ticket--);  

8.     }  

9.     }  

10.   }  

11.   }  

12.   package org.demo.runnable; 

13.   public class RunnableTicket { 

14.   public static void main(String[] args) { 

15.   MyThread mt=new MyThread();  

16.   new Thread(mt).start();//同一个mt,但是在Thread中就不可以,如果用同一 

17.   new Thread(mt).start();//个实例化对象mt,就会出现异常 

18.   new Thread(mt).start(); 

19.   }  

20.   }; 

虽然现在程序中有三个线程,但是一共卖了10张票,也就是说使用Runnable实现多线程可以达到资源共享目的。

 

0 0
原创粉丝点击