你的位置:首页 > Java教程

[Java教程]多线程——线程模型


什么是程序?

安装在磁盘上的一段指令集合,它是静态的概念。

什么是进程?

它是运行中的程序,是动态的概念,每个进程都有独立的资源空间。

什么是线程?

线程,又称为轻量级进程,是程序执行流的最小单元,是程序中一个单一的顺序控制流程。线程是进程的一个实体,是被系统独立调度和分派的基本单位。

什么是多线程?

多线程则指的是在单个程序中可以同时运行多个不同的线程执行不同的任务。

 

多线程的特点

①   一个进程可以包含一个或多个线程。

②   一个程序实现多个代码同时交替运行就需要产生多个线程。

③   线程本身不拥有系统资源,与同属一个进程的其它线程共享所在进程所拥有的资源。

④   同一进程中的多个线程之间可以并发执行。CPU会随机抽出时间,让我们的程序一会做这件事情,一会做另外一件事情。

 

多线程的目的

就是“最大限度地利用CPU资源”,当某一线程的处理不需要占用CPU而只和I/O等资源打交道时,让需要占用CPU资源的其它线程有机会获得CPU资源。从根本上说,这就是多线程编程的最终目的。

 

Java运行系统在很多方面依赖于线程,所有的类库设计都考虑到多线程。Java是纯面向对象语言,Java的线程模型也是面向对象的。

 

创建线程

通过继承Thread类创建线程

①   普通Java类如继承自Thread类,就成为一个线程类,并可通过该类的start方法来启动线程,执行线程代码。

②   Thread类的子类可直接实例化,但是子类中必须覆盖run方法才能真正运行线程的代码。

 

通过实现Runnable接口创建线程

①   实现Runnable接口的类必须借助Thread类才能创建线程。通过Runnable接口创建线程分为两步:

a)         创建实现Runnable接口的类的实例。

b)         创建一个Thread类对象,将第一步实例化得到的Runnable对象作为参数传入Thread类的构造方法。

②   通过Thread类的start方法启动线程。

 

Code:

继承Thread创建线程

 1 class HelloThread extends Thread { 2   public HelloThread(String name){ 3     super(name); 4   } 5   @Override 6   public void run() { 7     for (int i = 0; i < 5; i++) { 8       //获取线程的名称 9       System.out.println(this.getName()+":"+i);10     }11   }12 }

主方法:

1     HelloThread h1 = new HelloThread("a");//构造方法中设置线程名称  2     //h1.setName("线程1");//设置线程名称(默认构造)  3     h1.start();//开始线程4     HelloThread h2=new HelloThread("b");5     //h2.setName("线程2");6     h2.start();

多次执行程序,执行结果不同,说明线程一旦开启,随机执行。

 

使用Runnable接口创建线程

 1 class HelloRunnable implements Runnable { 2  3   @Override 4   public void run() { 5     for (int i = 0; i < 5; i++) { 6       // 获取线程的名称 7       System.out.println(Thread.currentThread().getName() + ":" + i); 8     } 9   }10 11 }

主方法:

1     HelloRunnable helloRunnable = new HelloRunnable();2     Thread t1 = new Thread(helloRunnable, "A");3     t1.start();4     Thread t2 = new Thread(helloRunnable, "B");5     t2.start();

使用Runnable接口创建线程有以下2个好处:

1、避免单继承的局限,一个类可以实现多个接口,但是只能继承一个类

2、适合资源共享

 

举例:在2个窗口中出售5张票:

使用Thread创建线程时:

 1 class TickThread extends Thread { 2   private int ticket = 5; 3  4   public TickThread(String name) { 5     super(name); 6   } 7  8   @Override 9   public void run() {10     while (true) {11       System.out.println(this.getName()+":"+(ticket--));12       if(ticket<1){13         break;14       }15     }16   }17 }

主方法:

1     TickThread s1=new TickThread("一号窗口");2     s1.start();3     TickThread s2=new TickThread("二号窗口");4     s2.start();

执行后发现,2个窗口各出售了5张票

 

使用Runnable接口创建线程时:

 1 class TickRunnable implements Runnable{ 2   private int ticket = 5; 3  4   @Override 5   public void run() { 6     while (true) { 7       System.out.println(Thread.currentThread().getName()+":"+(ticket--)); 8       if(ticket<1){ 9         break;10       }11     }12   }13   14 }

主方法:

1     TickRunnable runnable=new TickRunnable();2     Thread t1=new Thread(runnable, "一号窗口");3     t1.start();4     Thread t2=new Thread(runnable, "二号窗口");5     t2.start();

执行后可以看到5张票由2个窗口共同出售,因为只产生了一个对象