Java多线程概念

 

多线程概念
通常线程是在系统层被实现的。java是第一个在语言中实现的。java在语言级提供了对多线程设计的支持。

程序:是计算机指令的集合,它以文件的形式存储在磁盘上。

进程:是一个程序在其自身的地址空间中的一次执行活动。进程是资源申请、调度和独立运行的单位,因此,它使用系统中的运行资源;而程序不能申请系统资源,不能被系统调度,也不能作为独立运行的单位,因此,它不占用系统的运行资源。

线程:是进程中的一个单一的连续控制流程。一个进程可以拥有多个线程。
线程又称为轻量级进程,它和进程一样拥有独立的执行控制,由操作系统负责调度,区别在于线程没有独立的存储空间,而是和所属进程中的其它线程共享一个存储空间,这使得线程间的通信远较进程简单。

并发编程:在计算机编程中有一个基本概念,就是在同一时刻处理多个任务的思想。许多程序设计问题都要求程序能够停下正在做的工作,转而处理某个其他问题,然后再返回主进程。有许多方法可以实现这个目的。最初,程序员们用所掌握的有关机器底层的知识来编写中断服务程序,主进程的挂起是通过硬件中断来触发的。尽管这么做可以解决问题,但是其难度太大,而且不能移植,所以使得将程序移植到新型号的机器上时,既费时又费力。有时中断对于处理时间性强的任务是必需的,但是对于大量的其他问题,我们只是想把问题切分成多个可独立运行的部分(任务),从而提高程序的响应能力。在程序中,这些彼此独立运行的部分称之为线程,上述概念被称为“并发”。并发最常见的例子就是用户界面。通过使用任务,用户可以在揿下按钮后快速得到一个响应,而不用被迫等待到程序完成当前任务为止。

为什么要使用多线程?

多线程帮助你写出CPU最大利用率的高效程序。举例来说,网络的数据传送速率远远低于CPU处理能力,本地文件系统资源的读写速度也远远低于CPU的处理能力,在传统的单线程环境中,你的程序必须等待每一个这样的任务完成以后才能执行下一步--尽管CPU大部分时间处于空闲。而JAVA的多线程能使你充分利用这些空闲的时间。在一个单线程程序中如果出现阻塞则整个程序都可能停止运行,而在一个多线程的程序中这不会出现这样的问题。当一个线程阻塞时,别的线程会运行,这样可以大大的提高CPU效率。

java线程模型

在程序的执行过程当中,某一个时刻只能有一个线程运行,那为什么我们在启动多个进程或者一个进程多个线程的时候,我们看到这几个进程或线程在同时运行呢?这是因为在单个CPU的情况下,操作系统决定会在一个极短的时间片段中执行一个线程,那么当这个时间片段运行结束以后,系统会决定运行其他的一个线程。因为这个时间片段很短,频繁着发生切换,给我们的感觉就好象是这几个线程同时在运行一样。
问题:既然在单CPU情况下,某一个时刻只能有一个线程运行,那么我们为什么要设计多线程呢?我们能不能够设计多进程来代替多线程呢?
我们在程序设计的时候应该考虑到程序的可移植性,当这个程序放到多CPU平台下的时候,同时运行多个线程,从而达到真正意义上的并发运行。至于能不能用多进程代替多线程,前面就已经说明了。

java线程优先级
java自动给每个线程安排优先级以决定与其他线程比较时该如何对待该线程。线程的优先级是用来决定何时从一个运行的线程切换到另一个,这叫“上下文转换”。Java使用本身的线程调度器来安排线程的运行。java的线程调度器是抢占式的分配进程(分配给每个线程相等的CPU时间的进程)。抢占式调度模型就是许多线程处于可以运行状态(等待状态),但实际上只有一个线程在运行。该线程一直运行到它终止进入可运行状态(等待状态),或者另一个具有更高优先级的线程变成可运行状态。在后一种情况下,低优先级的线程被高优先级的线程抢占,高优先级的线程获得运行的机会。 具有高优先级的线程它会抢占底优先级线程运行的机会,但是这个不是绝对的,一个长时间处于等待状态的底优先级线程仍然可能被线程调度器来选择运行。Java线程调度器支持不同优先级线程的抢先方式,但其本身不支持相同优先级线程的时间片轮换。但是Java运行时系统所在的操作系统(例如:Windows2000)支持时间片的轮换,那么Java也就支持相同优先级线程的时间片轮换。

主线程
java程序都有的线程:主线程。当java程序启动时,一个线程立即运行,该线程通常叫做

程序的主线程。因为他是程序开始时就执行的。主线程的重要性体现在两方面:
1,它是产生其他子线程的线程。
2,通常他必须最后完成执行,因为它执行各种关闭动作。
主线程是可以控制的。可以由一个Thread对象控制。可以用currentThread()获得这个主线程的引用。然后你就可以像控制其他线程那样控制这个主线程。
比如:
class CurrentThreadDemo{
public static void main(String args[]){
Thread t=Thread.currentThread();//这样就获得了这个主线程的引用。
System.out.println("Current thread:"+t)
}
}

建立线程
要创建多线程,可以使用继承thread类和实现Runnable接口。
实际上thread类也是实现了Runnable接口。
Runnable接口有一个run方法。所有实现接口Runnable的对象都要实现这个方法来创建一个线程。想要启动这个线程都要调用对象的run方法,比如thread类中的start方法。run()方法能够像主线程那样调用其他方法,引用其他类,声明变量。仅有的不同是run()在程序中确立另一个并发的现成执行入口。当run()返回时,该线程也就结束了。继承thread也是一样的,继承thread的类使用要方法重载run()方法来创建线程。
thread和Runnable的区别:
为什么java会有两种创建子线程的方法?那一种更好?Thread类定义了多种方法可以被派生类重载。如果你不需要重载Thread的其他方法时,最好只实现Runnable接口。

使用isAlive()和join()
一个线程如何知道另一个线程已经结束?
有两种方法可以判定一个线程是否结束:
1,可以在现成中调用isAlive().
2,调用join().

线程的同步
当两个或两个以上的线程需要共享资源,他们需要某种方法来确定资源在某一刻仅被一个线程占用,达到此目的的过程叫做同步(synchronization).
同步有两种方法:同步块和同步方法。
synchronization(任何一个对象){//同步块
//需要保护的临界区
}
原理:在java中每一个对象都有一个监视器或者叫做锁。当运行到synchronization(obj)的时候会判断obj这个对象是否上锁,如果没有,那么虚拟机会给他上锁。然后向下运行,当运行完这个块后,才会解锁,只有解锁以后其余需要共享资源的线程才能运行。在这个期间需要和这个线程共享资源的线程都挂起等待。
public synchronization void tempNameFunction(){//同步方法
//需要保护的临界区
}
原理:当线程进入到这个方法时,会自动生成一个this对象,由this对象来上锁。这和synchronization 块是一样,只不过一个是任意对象,一个是this对象。

线程间的通信:
线程他远离了轮询,轮询通常由重复监测条件的循环实现。一旦条件成立,就要采取适当的行动。这浪费了CPU时间。
假设数据产生器必须等待消费者完成工作才能产生新的数据。在轮询系统中,消费者在等待生产者产生数据时会浪费很多CPU周期。一旦生产者完成工作,它将启动轮询,浪费更多的cpu时间等待消费者的工作结束,这样情况不受欢迎。
为了避免轮询,java包含了通过wait(),notify()和notifyAll()方法实现的一个进程间通信机制。这些方法在Object类中是用final方法实现的。所以所有的类都含有他们。这三个方法仅在synchronized方法中才能调用。

SOURCE: http://hi.baidu.com/wwwanq/blog/item/e5b4a2d592888009a08bb701.html

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值