10线程知识点

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
线程是JAVA的高级部分,我们的重点是理解JAVA中线程的概念,原理为今后的的学习高级部 分,以及面试做准备。然后是多线程的实现方式以及简单的启动,停止线程方法,为游戏做准 备。
多任务处理: 什么是多任务呢?多任务就是几个任务同时运行。在我们上网的 时候,即可以聊天,也可以听音乐,也可以浏览网页。这就是多任务。 它有个特点:就是在一个任务还没有做完的的时候,又去做另外的任 务。 在程序里的多任务处理是怎么样的呢?它也是指在同一个时候执 行多个任务,它不必等到某个任务执行完之后,再去做其他的任务。 CPU在处理的时候,先是执行一个任务的一段代码,然后接着执行另一 个任务的一段代码。交替执行直到任务结束。 现实生活中这样的例子是很多的。如:有个柜台只有一个营业 员。这时候来了二个顾客。那么这个营业员应该怎么样去应对呢?她问 第一个顾客要买什么商品,然后把商品给第一个顾客看;在第一个顾客 看的时候,又去问第二个顾客要买什么商品,然后把商品给第二个顾客 看。在第二个顾客看时候,又去问第一个顾客对商品满不满意。如果顾 客说再看看,那么营业员又去问第二个顾客满不满意。如果第二个顾客 说满意,营业员就叫顾客付款,然后结束第二个顾客的营业任务,然后 再去问第一个顾客满不满意。如果第一个顾客也满意付款。那么整个任 务就结束了。 多任务处理的2种类型: u多任务处理有两种类型: - 基于进程 - 基于线程 u进程是指一种“自包容”的运行程序,有自己的地址空间; 当我们打开windows任务管理器的时候,就有一个进程的选项 卡。在这个选项卡里,我们可以发现有很多当前计算机正在运行的应用 程序。这些正在运行的每一个应用程序都叫一个进程。它们都会占用一 定的内存,都有自己的地址空间。
在上面的示例中,我们是开启了一个进程,用指定地址的应用程序(这里是记事本),去打开 指定的文件(这里是C盘下的2.txt)
线程
和多进程不同,什么是多线程呢?线程是进程内部单一的一个顺序控制流。所以一个进 程包含很多线程。基于线程的多任务处理环境中,线程是最小的处理单位 我们在使用word文档时,打开一个文件菜单,这就是开启了一线程,把一行字选中,加 粗,这也是一个线程。线程的概念其实很简单,线程就是程序运行时的路径,它决定将要执行 什么代码。所以当我们运行main方法时,其实就已经开启了一个线程了。
就是去执行实现了Runnable接口的类对象里重写的run()方法。 上面两种方法都可以实现线程的启动,但通常采用第二种方法启动线 程,原因是如果一个类继承了另一个类的时候,那么就不能再继承其 他类了,但接口可以多实现,所以实现接口的方式更加灵活一些。 线程启动之后,会有不同的状态,它有什么样的状态呢?
么要调用start()方法呢?上面例子中,main()方法改为 One one=new One();//创建线程对象 one.run();//启动线程 for(int i=65;i<75;i++){//打印字母 System.out.println((char)i); } 不也一样吗? 这样的想法是错误的。因为启动线程是使用start()方法。这时候在主 线程之外另外开启了一个线程,就是说主线程不必等到子线程结束以后 再进行其他的动作。所以这时候字母和数字循环打印。而如果直接调用 run()方法,其实只是普通方法的调用,并没有开启一个线程,所以是单 线程的程序。上面例子中,就不会是数字和字母交替打印,而是先把数 字打印完毕,再打印字母。
} catch(InterruptedException e) { System.out.println("主线程被中断"); } }
在这个例子中,是单线程的程序,而main方法所在的线程就是主线程。那么如何去通过这个 主线程去启动一个子线程呢?
u通过以下两种方法创建 Thread 对象: 1、- 声明一个 Thread 类的子类,并覆盖 run() 方法。 public class Threads { public static void main(String[] args) { One one=new One();//创建线程对象 one.start();//启动线程 for(int i=65;i<75;i++){//打印字母 System.out.println((char)i); } } } class One extends Thread{//继承Thread线程对象 public void run(){//启动线程后自动调用子类重写父类的run()方 法 for(int i=0;i<10;i++){ System.out.println(i); } } } 在上面的例子中定义了一个线程,并且重写了父类的run()方法。然后在 main方法这个主线程中启动这个线程,启动一个线程使用线程对象的 start()方法。这时候就用自动的调用父类的run()方法,循环打出一串数 字。在main主线程里也有一个循环,是打出字母。因为是两个线程同时 候运行,这时候打印的结果是数字和字线交替打印。说明主线程不必等 到子线程结束以后,就继续执行下面的语句。有些同学可能会说了,既 然启动线程是调用run()方法。那么我直接调用run()方法不就行了,为什
u在Java程序启动时,一个线程立刻运行,该线程通常称为程序的主线程。也就是main方法 运行时就产生一个主线程。 u主线程的特点: –最先开始
–最后结束 –由他产生其他子线程 –通常它必须最后完成执行,因为它执行各种关闭动作。 这在上例中,孙悟空就好比是主线程,它变出的三个小猴子是子线程。小猴子是由孙悟空这 个主线程产生的,小猴子打死妖精之后,由孙悟空再把小猴子回收成毫毛。 代码示例:
u线程间的切换成本比进程间切换成本低
那么什么又是单线程,什么又是多线程呢?
public static void main(String[] args){ a(); b(); c(); } 代码执行的顺序图如下:
在上面的例子里,大家可以看出,在main方法里执行时,必须要等到 a()方法执行完了之后,才能执行b()方法。b()方法执行完以后才能执 行C()方法。这样在等到一个方法执行完以后再执行另一个方法的模式 叫单线程。我以前用到的程序大部分都是单线程的。 那么多线程是怎么一回事呢?
public static void main(String[] args){ //获得当前线程对象,即主线程 Thread t= Thread.currentThread(); System.out.println("当前线程是: "+t); //输出结果:"当前线程是: Thread[main,5,main]" /*在中括号中第一个main指的是线程的名字, * 5指的是线程的优先级, * 第二个main是线程所在的线程组 */ t.setName("主线程"); //设置线程名字 // System.out.println("当前线程名是: "+t); 输出结果是:"当前线程名是: Thread[主线程,5,main]" try { for(int i=0;i<3;i++) { System.out.println(i); /* * 线程休眠1500毫秒 * 就是线程暂时停止运行1500毫秒 * * sleep是线程类Thread的静态方法, * 指的是当前线程休眠1500毫秒(这里是主线程) */ Thread.sleep(1500); }
从上面的图可以看出线程经常处于暂时停止执行的状态,那么什么时候 线程暂时停止执行呢?
u线程:
-线程优先级比较低,因此它不能获得 CPU 时间。 -使用 sleep( ) 方法使线程睡眠。 -通过调用 wait( ) 方法,使线程等待。 -通过调用 yield( ) 方法,线程已显式出让CPU控制Βιβλιοθήκη Baidu。(挂 起) -线程由于等待一个文件I/O事件被阻塞。
u基于进程的特点是允许计算机同时运行两个或更多的程序。 在JAVA中是可以启动一个进程的。就是说通过JAVA代码,我们可以打开 另一个应用程序
代码示例:
//创建一个操作系统进程,用指定的的应用程序去打开指定的文件 ProcessBuilder process=new ProcessBuilder( "C:/WINDOWS/NOTEPAD.EXE",//应用程序地址 "c:/2.txt");//文件地址 try { process.start();//启动进程 } catch (IOException e) { e.printStackTrace(); }
基于线程的多任务处理的优点
u基于线程所需的开销更少 –在多任务中,各个进程需要分配它们自己独立的地址空间 –多个线程可共享相同的地址空间并且共同分享同一个进程 网站是个很典型的多任务处理的例子,当不同的用户同时去访问一个网站时,网站 就需要进行多任务处理。以前使用CGI(通用网关接口技术),CGI是一个多进程的技术,当一 个用户去访问网站时,是开启一个进程,这样的话,当有多个用户同时访问时,那么就得开启 多个进程。每一个进程都有自己独立的地址空间,所以这样的网站内存很快就消耗掉了。不但 可连接的用户少,而且很容易受到恶意攻击。在JAVA里,采用的servlet技术,是一个基于多线 程的技术,共享同一个进程,共享相同的地址空间,这样的话,当有多个用户同时访问时,性 能不会下降多少。 u进程间调用涉及的开销比线程间通信多
u缺省优先级为 NORM_PRIORITY 5级 u有关优先级的方法有两个:
-final void setPriority(int newp) : 修改线程的当前优先级 -final int getPriority() : 返回线程的优先级
代码示例: public class Threads { public static void main(String[] args) { One one=new One(); Thread two=new Thread(new Two()); one.setPriority(1);//设置第一个线程优先级为1级 two.setPriority(10); //设置第二个线程优先级为10级 one.start();//启动第一个线程 two.start();//启动第二个线程 } } class One extends Thread{ public void run(){ System.out.println("第一个线程"); } }
线程优先级 线程是有优先级的,就是说当两个线程同时启动或同时去访问一个 对象时,优先级高的线程会拥有更高的访问权。线程的优先级有1—10 级,数字越大,优先级越高。
uJava 中的线程优先级是在 Thread 类中定义的常 量
-NORM_PRIORITY : 值为 5 -MAX_PRIORITY : 值为 10 -MIN_PRIORITY : 值为 1
2、声明一个实现 Runnable 接口的类,并实现 run() 方法。
public class Threads { public static void main(String[] args) { Thread two=new Thread(new Two());//创建线程对象,而其中 的参数是实现了Runnable接口的类对象。 two.start();//启动线程 } } class Two implements Runnable{//实现Runnable接口,并实现这个 接口定义的run()方法 public void run() { System.out.println("线程启动"); } } 上面的例子是由一个类去实现Runnable接口,然后实现Runnable里定义 的run()方法。然后再定义一个Thread线程类对象,将这个实现了 Runnable接口的类对象作为参数传过去。这样的话,就是把线程对象和 这个实现了Runnable接口的类对象作了一个关联,在启动线程的时候,
在上面的例子,可以看出,多线程是多个方法同时执行,在a()方法执 行时,同时执行b()方法,换句话说,b()方法不必等到a()方法执行完 以后再去执行。这就是多线程。就是说在一个程序中,同时有多个执行 路径存在。 《西游记》里孙语空去打妖精,这时候他一个人去打三个妖精,它要把 一个妖精打死之后,才能去打第二个妖精,第二个妖精打死之后,再打 第三个妖精。这时候它是单线程的。一个打妖精很累,它就拔三根毫 毛,变成三个小孙悟空,一个小孙悟空打一个妖精,就是说它不必等到 第一个妖精打死之后再去打第二个妖精,而是同时去打。这就叫多线 程。
相关文档
最新文档