多线程的创建方式

一:进程与线程       
       进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1--n个线程。(进程是资源分配的最小单位)
  线程:同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换开销小。(线程是cpu调度的最小单位)
  线程和进程一样分为五个阶段:创建、就绪、运行、阻塞、终止。
  多进程是指操作系统能同时运行多个任务(程序)。
  多线程是指在同一程序中有多个顺序流在执行。
2:实现多线程有三种方法:一种是继续Thread类,另外一种是实现Runable接口.第三种是实现Callable接口通过FutureTask包装器来创建Thread线程
//继承Thread类
public class MyThread extends Thread{ 
 public void run(){
  //重写run方法
  }
}
new MyThread().start();//创建并启动线程


//实现Runnable接口
public class MyThread2 implements Runnable { 
 public void run(){
  //重写run方法
  }
}
 //创建并启动线程
    MyThread2 myThread=new MyThread2();
    Thread thread=new Thread(myThread);
    thread().start();


//实现Callable接口,使用FutureTask包装
 FutureTask<String> ft = new FutureTask<String>(new Callable<String>() {
            
             @Override
             public String call() throws Exception {
                 System.out.println("new Thread 3");//输出:new Thread 3
                 return "aaaa";
             }
         });
         
         Thread t3 = new Thread(ft);
         t3.start();
         String result = ft.get();//法会阻塞,直到子线程执行结束才返回
         System.out.println(result);//输出:aaaa
         
     }
View Code

直接调用线程的run方法时,并不是多线程,只是一个普通顺序方法。必须调用start方法才是多线程的调用方式

3.区别

实现Runnable和实现Callable接口的方式基本相同,不过是后者执行call()方法有返回值,前者线程执行体run()方法无返回值,因此可以把这两种方式归为一种这种方式与继承Thread类的方法之间的差别如下:

<1、线程只是实现Runnable或实现Callable接口,还可以继承其他类。

<2、这种方式下,多个线程可以共享一个target对象,非常适合多线程处理同一份资源的情形。

<3、但是编程稍微复杂,如果需要访问当前线程,必须调用Thread.currentThread()方法。

<4、继承Thread类的线程类不能再继承其他父类(Java单继承决定)。

4.线程状态转换

<1、新建状态(New):新创建了一个线程对象。
<2、就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权。
<3、运行状态(Running):就绪状态的线程获取了CPU,执行程序代码。
<4、阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:
(一)、等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待池中。(wait会释放持有的锁)
(二)、同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池中。
(三)、其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。(注意,sleep是不会释放持有的锁)
<5、死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

注:一般推荐采用实现接口的方式来创建多线程

在java中,每次程序运行至少启动2个线程。一个是main线程,一个是垃圾收集线程。因为每当使用java命令执行一个类的时候,实际上都会启动一个JVM,每一个jVM实际就是在操作系统中启动了一个进程。
 

猜你喜欢

转载自www.cnblogs.com/nzxj/p/10465833.html