1.早上总结了小组api
2.昨晚睡前总结:
一:线程的简介:
- 线程是程序运行的基本单元
- 执行一个程序,会建立一个进程,而这个进程至少建立一个线程(主线程,该程序运行的入口点)
- 进程(系统进程,用户进程)
- 进程与进程之间不共享内存(独立运行)
- 线程可以共享进程内存,且拥有一个 属于自己的 内存空间(线程栈),用来保存线程内部要使用的数据
- 操作系统将进程分成多个线程,可以在操作系统下并发执行,提高了程序的运行效率
注:一个cpu一次只能执行一条指令,操作系统为了提高程序的运行效率,会在一个线程空闲的时候撤下这个线程,然后让其他线程
来执行,叫做线程调度.表面上是同步运行,其实是单独的线程交替着运行,因为交替的时间很短(毫秒),所以人类的肉眼察觉不出来.
二:线程的好处
1.充分利用cpu资源:
计算机只有一块cpu,当程序发生阻塞时,会让cpu处于空闲状态,这样会造成资源浪费
而使用多线程,可以让cpu处于空闲状态的时候运行其他的线程,让cpu很难有空闲的时间,让cpu资源得到充分利用
2.简化编程模型:
如果程序只完成一项任务,那么只写一个单线程的程序,按这个任务的步骤完成即可.
但如果程序要完成多项任务,如果只写一个单线程的程序,就要只能从头到尾来逐步完成多项任务,
而如果编写多线程,那么可以多个线程同步运行,每个线程负责一个步骤,这样利于开发人员对程序的理解以及维护
3.简化异步事件的处理:
当一个服务器应用程序接收不同客户端连接时,最简单的处理方式是为每一个客户端连接建立一个线程,
监听线程负责监听来自客户端的请求,
问题来了,如果采用单线程来进行处理,当开始读取客户端发来的数据后,read()方法处于阻塞状态,导致这个应用程序
无法继续监听客户端的请求.因此,想在单线程中处理多个客户端的请求,就必须使用非阻塞的Socket连接和异步I/O.
然而,使用异步I/O比使用同步I/O更加难以控制,容易出错.
所以:使用多线程和同步I/O 更容易地处理多请求的异步事件
4.使用GUI更有效率:
如果使用单线程来处理GUI事件,那么就要使用循环来对随时可能发生的GUI事件进行扫描,在循环内部除了扫描GUI事件外,
还需要执行其他的程序代码,当这些代码太长时,GUI事件会被"冻结",一直到这些代码被执行完.
现代GUI框架(SWING \ AWT \ SWT)中,都使用了一个单独的事件分派线程(event dispatch thread, EDT) 来对事件进行扫描
,当我们按下一个按钮时,按钮的单击事件只会在这个时间分派线程被调用,.
由于EDT任务只对EDT事件进行扫描,所以会对事件的反应非常的迅速.
5.节约成本:
首先:提高程序的运行效率一般有三个方法
- 增加计算机的cpu个数
- 为一个程序启动多个进程
- 在程序中使用多线程
分析:
- 方法一容易做到但是成本非常的昂贵,这种方法不需要修改程序
- 方法二不用购买新的硬件,但是不容易共享数据,如果需要完成的任务需要共享数据,那么这种方式不太方便(并且启动多个进程会消耗大量的系统资源)
- 方法三弥补了方法一和方法二的缺点(不用昂贵成本,不用启动多个进程浪费系统资源),使用多线程可以模拟多块cpu的运行方式.
三:java的线程模型:
- 因为java是面向对象的,所以java的线程也是面向对象的.
- java通过Thread类将线程所必要的功能都封装起来,
- 想建立一个线程,必须有一个线程执行函数,对应Thread类的run()方法
- Thread类还有一个start()方法来负责建立线程(相当于windows的建立线程函数CreateThread)
- 当调用start()方法建立线程成功后会自动调用Thread类的run()方法.
- 所有继承Thread类都可以通过start()方法进行线程,想运行自己的线程执行函数,需要覆盖Thread类的run()方法
- 线程类的接口Runnable,这个接口只有一个抽象方法run()方法,要看是不是线程类,就看它是否实现了Runnable类的run()方法
注:因为java不支持多继承,因此继承了Thread类就不能继承其他类了,而实现Runnable接口就可以继承其他的必要类了.