多线程(英语:multithreading),是指从软件或者硬件上实现多个线程并发执行的技术。具有多线程能力的计算机因有硬件支持而能够在同一时间执行多于一个线程,进而提升整体处理性能。具有这种能力的系统包括对称、多核心处理器以及(Chip-levelmultithreading)或同时多线程(Simultaneousmultithreading)处理器。 在一个程序中,这些独立运行的程序片段叫作“线程”(Thread),利用它编程的概念就叫作“多线程处理(Multithreading)”。具有多线程能力的计算机因有硬件支持而能够在同一时间执行多于一个线程(台湾译作“执行绪”),进而提升整体处理性能。
线程定义
英文:Thread
每个正在系统上运行的 都是一个 。每个 包含一到多个线程。 也可能是整个 或者是部分的动态执行。线程是一组 的集合,或者是 的特殊段,它可以在里独立执行。也可以把它理解为运行的上下文。所以线程基本上是轻量级的 ,它负责在单个 里执行多 。通常由 负责多个线程的调度和执行。
线程是 中一个单一的顺序控制流程.在单个中同时运行多个线程完成不同的工作,称为多线程.
线程和 的区别在于,子和 父有不同的 和数据空间,而多个线程则共享数据空间,每个线程有自己的执行 和 为其执行上下文.多线程主要是为了节约CPU时间,发挥利用,根据具体 而定. 线程的运行中需要使用计算机的 资源和CPU。
缺点
·如果有大量的线程,会影响性能,因为 需要在它们之间切换。
·更多的线程需要更多的 空间。
·线程可能会给 带来更多“bug”,因此要小心使用。
·线程的中止需要考虑其对 运行的影响。
·通常块模型数据是在多个线程间共享的,需要防止线程 的发生。
一些线程模型的背景
可以重点讨论一下在 环境中常用的一些模型。
·单线程模型
在这种线程模型中,一个 中只能有一个线程,剩下的必须等待当前的线程执行完。这种模型的缺点在于系统完成一个很小的 都必须占用很长的时间。
·块线程模型( 多块模型STA)
这种模型里,一个 里可能会包含多个执行的线程。在这里,每个线程被分为 里一个单独的块。每个可以含有多个块,可以共享多个块中的数据。 规定了每个块中线程的执行时间。所有的请求通过 进行 ,这样保证了每个时刻只能访问一个块,因而只有一个单独的 可以在某一个时刻得到执行。这种模型比 模型的好处在于,可以响应同一时刻的多个用户请求的 而不只是单个用户请求。但它的性能还不是很好,因为它使用了 的线程模型, 是一个接一个得到执行的。
·多线程块模型(自由线程块模型)
多线程块模型(MTA)在每个 里只有一个块而不是多个块。这单个块控制着多个线程而不是单个线程。这里不需要 ,因为所有的线程都是相同的块的一个部分,并且可以共享。这样的 比 模型和STA的执行速度都要快,因为降低了系统的负载,因而可以优化来减少系统idle的时间。这些 应用一般比较复杂,因为 员必须提供 以保证线程不会并发的请求相同的资源,因而导致竞争 的发生。这里有必要提供一个锁机制。但是这样也许会导致系统死锁的发生。
和线程都是 的概念。 是 的执行实例,每个是由私有的虚拟 空间、 、数据和其它各种 组成,在运行过程中创建的资源随着的终止而被销毁,所使用的 在终止时被释放或关闭。
线程是 内部的一个执行单元。系统创建好 后,实际上就启动执行了该的主执行线程,主执行线程以函数 形式,比如说或WinMain函数,将 的启动点提供给Windows系统。主执行线程终止了, 也就随之终止。
每一个 至少有一个主执行线程,它无需由用户去主动创建,是由系统自动创建的。用户根据需要在 中创建其它线程,多个线程并发地运行于同一个 中。一个 中的所有线程都在该的 空间中,共同使用这些空间、 和系统资源,所以线程间的通讯非常方便, 的应用也较为广泛。多线程可以实现 ,避免了某项 长时间占用CPU时间。要说明的一点是,到2015年为止,大多数的计算机都是单处理器(CPU)的,为了运行所有这些线程, 为每个独立线程安排一些CPU时间,以轮换方式向线程提供 ,这就给人一种假象,好象这些线程都在同时运行。由此可见,如果两个非常活跃的线程为了抢夺对CPU的控制权,在线程切换时会消耗很多的CPU资源,反而会降低系统的性能。这一点在多线程编程时应该注意。C++ 11 标准中,STL类库也实现了多线程的类std::thread,使得多线程编程更加方便。
Thread
类Runnable
接口run()
方法 和start()
方法
- 所有在线程要做的事,即线程体,都写在
run()
方法里面,等待调用,这部分往往处理网络通信和数据库处理。 start()
的使用是开始线程的标志。也是线程的生命周期开始的地方。无论用前面的那种方式使用线程。
举例使用线程
使用Runnable实现
/** * 实现Runnable接口的类 */ public class DoSomething implements Runnable { private String name; public DoSomething(String name) { this.name = name; } public void run() { for (int i = 0; i < 5; i++) { for (long k = 0; k < 100000000; k++) ; System.out.println(name + ": " + i); } } } /** * 测试Runnable类实现的多线程程序 */ public class TestRunnable { public static void main(String[] args) { DoSomething ds1 = new DoSomething("阿三"); DoSomething ds2 = new DoSomething("李四"); Thread t1 = new Thread(ds1); Thread t2 = new Thread(ds2); t1.start(); t2.start(); } }
使用Thread类实现:
/** * 测试扩展Thread类实现的多线程程序 */ public class TestThread extends Thread{ public TestThread(String name) { super(name); } public void run() { for(int i = 0;i<5;i++){ for(long k= 0; k <100000000;k++); System.out.println(this.getName()+" :"+i); } } public static void main(String[] args) { Thread t1 = new TestThread("阿三"); Thread t2 = new TestThread("李四"); t1.start(); t2.start(); } }
在整个Java线程中,实现并不是最难的,相反,线程有要注意的几个难点:
- 线程的生命周期
- 线程的优先级与线程调度
- 线程同步
定时器
Future接口
Java多线程执行框架
线程执行框架启动线程
将要多线程执行的任务封装为一个Runnable对象,将其传给一个执行框架Executor对象, Executor从线程池中选择线程执行工作任务。创建多线程框架对象调用线程执行任务
我们通常通过Executors类的一些静态方法来实例化Executor或ThreadPoolExecutor对象:比如Executor对象来执行:
public class ThreadTest { public static void main(String[] args) { Executor executor = Executors.newSingleThreadExecutor(); executor.execute(new MyRunnable()); } } class MyRunnable implements Runnable { @Override public void run() { System.out.println("running"); } }
比如线程池的Executor对象来执行:
public class ThreadTest { public static void main(String[] args) { ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors .newFixedThreadPool(3); executor.execute(new MyRunnable()); } } class MyRunnable implements Runnable { @Override public void run() { System.out.println("running"); } } 目前就学了这些 以后会补充的!!!!