java 多线程总结
2016-03-03 19:03
555 查看
一个人炫耀什么,说明内心缺少什么。
首先是概念:
进程 : 内存中运行的一个应用程序,占有一定、独立的内存空间。
线程 : 一个进程中的多个执行流程,一个进程可以启动多个线程,线程不会单独占用内存空间。
多个进程的内部数据和状态都是完全独立的,多线程共享一块内存空间和一组系统资源(同一进程内),在程序内部可以互相调用(通过对象方法)。
创建线程的两个方法
1、extends Thread
2、implements Runnable 都要重写 run() 方法
线程的生命周期
1、新建状态 (new了一个线程对象)
2、就绪状态 (调用 start() 方法)
3、运行状态 (运行 run() 方法)
4、阻塞状态 (线程由于某种原因(wait()、sleep()、同步阻塞)放弃CPU使用权,解除阻塞时重新转入就绪状态)
5、死亡状态(run() 方法运行完)
sleep() 方法: 将线程先挂起
getPriority() 方法 : 获得优先级
yield() 方法 : 放弃CPU使用权
例子: 实现每隔一秒打印当前时间
---------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------
结果:
------------------------------------------------------------------------------------------------------------------------
线程的同步
线程的同步其实就是线程安全问题。
当多线程共享数据的时候,线程会并发访问竞争资源,会对属性做改动,出现一些错误,这是应实现线程的同步
实现线程的同步主要有两种方式
1、同步代码块
2、同步方法
例子: 4个窗口售10张票的例子
----------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------------
结果:
当不实现同步时结果如下,代码就不发了(synchronized去掉就好)。
会出现每次运行结果都不一样,多个线程并发访问竞争资源,可见同步的重要性。
这里说下StringBuffer和StringBuilder
因为StringBuffer是线程安全的,所以要运行相关算法,所以速度上会比StringBuilder慢。
或者这样想,竞争无规则的卖票比你有一定规则的卖票会更快些。
线程的通信
wait()方法 :使线程进入等待状态
notify()方法 : 唤醒正在等待的线程
notifyAll()方法 : 唤醒正在等待的所有线程
例子
:生产者消费者模型 (厨师做馒头放盘子里,盘子最多放6个馒头,顾客吃盘子里的馒头,一共生产20个馒头)
明确以下几点:
1、厨师只在盘子没满时生产馒头。
2、顾客只在盘子有馒头时吃馒头。
3、盘子馒头满了,厨师提醒顾客可以吃馒头了。
4、盘子馒头没了,顾客提醒厨师可以生产馒头了。
-------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------
结果:
线程池
概念:
1 首先创建一些线程,他们的集合称为线程池,当服务器接收到用户的请求后,就从线程池中取出一个空闲的线程为之服务,服务器完成任务后不关闭该线程,还回线程池中。
2 在线程池的编程模式下,任务提交给线程池,而不是提交给单独的线程,线程池拿到任务后,他就在内部找有无空闲线程,再把任务交给一个空闲线程。
3 一个线程同时只能执行一个任务,但是同时可以向线程池分配多个任务
线程池好处
1 降低资源消耗,通过重复利用已创建好的线程,降低创建和销毁线程所需时间
2 提高响应速度,任务到达后,任务不需等待创建线程就立即运行
3 提高线程的可管理性
线程池主要部分
1 线程池管理器(ThreadPool)用于创建并管理线程池,包括创建和销毁线程池,添加新任务
2 工作线程(PoolWork)线程池中的线程,在没有任务时,处于等待状态,可以循环执行任务
3 任务接口(Task)每个任务必须实现这个接口,以供工作线程调度任务执行,它主要规定了任务的入口,任务执行完后的收尾工作
4 任务队列:用于存放没有处理的任务,提供一个缓冲机制
什么时候使用线程池
线程所需时间
创建时间 T1
服务时间 T2
销毁时间 T3
当 T1+T3 》 T2 使用线程池
实现线程池的方法
1 ---Executors.newCachedThreadPool()
创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用
2 ---Executors.newFixedThreadPool (int nThreads) (常用)
创建一个有固定数量线程的线程池
例子 :每隔一秒输出一次当前线程的名字,总计输出5次,创建一个线程池,该线程池中创建两个线程,
使线程池执行3次步骤一的任务
----------------------------------------------------------------------------------------------------------------
结果:
由于线程的通信中的生产者- 消费者模型 每次都要放馒头,取馒头 ,唤醒线程,等待线程,效率时间方面会差些,
用BlockingQueue 队列 可以解决这一问题。
ArrayBlokingQueue:(阻塞队列) 相关方法:
1、add(Object):将Object加入到队列中,如果队列可以容纳,则返回true,否则抛出异常
2、offer(Object):表示如果可能的话,将Object加入到队列中,如果能放进去,返回true,否则返回false
3、put(Object):将Object加入到队列中,如果队列没有空间,调用此方法的线程被阻塞直到队列中有空间再继续(一般用)
4、poll(time):取走队列中排在首位的元素对象,如果队列为空,则可以等待给定的time时间,取不到元素,返回null
5、take():取走队列中首位元素对象,如果队列为空,把调用该方法的线程阻塞。直到有元素加入到队列。(一般用)
这里给个例子,馒头换成苹果,其他一致。
------------------------------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------
输出:
一个人炫耀什么,说明内心缺少什么。
首先是概念:
进程 : 内存中运行的一个应用程序,占有一定、独立的内存空间。
线程 : 一个进程中的多个执行流程,一个进程可以启动多个线程,线程不会单独占用内存空间。
多个进程的内部数据和状态都是完全独立的,多线程共享一块内存空间和一组系统资源(同一进程内),在程序内部可以互相调用(通过对象方法)。
创建线程的两个方法
1、extends Thread
2、implements Runnable 都要重写 run() 方法
线程的生命周期
1、新建状态 (new了一个线程对象)
2、就绪状态 (调用 start() 方法)
3、运行状态 (运行 run() 方法)
4、阻塞状态 (线程由于某种原因(wait()、sleep()、同步阻塞)放弃CPU使用权,解除阻塞时重新转入就绪状态)
5、死亡状态(run() 方法运行完)
sleep() 方法: 将线程先挂起
getPriority() 方法 : 获得优先级
yield() 方法 : 放弃CPU使用权
例子: 实现每隔一秒打印当前时间
---------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------
结果:
------------------------------------------------------------------------------------------------------------------------
线程的同步
线程的同步其实就是线程安全问题。
当多线程共享数据的时候,线程会并发访问竞争资源,会对属性做改动,出现一些错误,这是应实现线程的同步
实现线程的同步主要有两种方式
1、同步代码块
2、同步方法
例子: 4个窗口售10张票的例子
----------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------------
结果:
当不实现同步时结果如下,代码就不发了(synchronized去掉就好)。
会出现每次运行结果都不一样,多个线程并发访问竞争资源,可见同步的重要性。
这里说下StringBuffer和StringBuilder
因为StringBuffer是线程安全的,所以要运行相关算法,所以速度上会比StringBuilder慢。
或者这样想,竞争无规则的卖票比你有一定规则的卖票会更快些。
线程的通信
wait()方法 :使线程进入等待状态
notify()方法 : 唤醒正在等待的线程
notifyAll()方法 : 唤醒正在等待的所有线程
例子
:生产者消费者模型 (厨师做馒头放盘子里,盘子最多放6个馒头,顾客吃盘子里的馒头,一共生产20个馒头)
明确以下几点:
1、厨师只在盘子没满时生产馒头。
2、顾客只在盘子有馒头时吃馒头。
3、盘子馒头满了,厨师提醒顾客可以吃馒头了。
4、盘子馒头没了,顾客提醒厨师可以生产馒头了。
-------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------
结果:
线程池
概念:
1 首先创建一些线程,他们的集合称为线程池,当服务器接收到用户的请求后,就从线程池中取出一个空闲的线程为之服务,服务器完成任务后不关闭该线程,还回线程池中。
2 在线程池的编程模式下,任务提交给线程池,而不是提交给单独的线程,线程池拿到任务后,他就在内部找有无空闲线程,再把任务交给一个空闲线程。
3 一个线程同时只能执行一个任务,但是同时可以向线程池分配多个任务
线程池好处
1 降低资源消耗,通过重复利用已创建好的线程,降低创建和销毁线程所需时间
2 提高响应速度,任务到达后,任务不需等待创建线程就立即运行
3 提高线程的可管理性
线程池主要部分
1 线程池管理器(ThreadPool)用于创建并管理线程池,包括创建和销毁线程池,添加新任务
2 工作线程(PoolWork)线程池中的线程,在没有任务时,处于等待状态,可以循环执行任务
3 任务接口(Task)每个任务必须实现这个接口,以供工作线程调度任务执行,它主要规定了任务的入口,任务执行完后的收尾工作
4 任务队列:用于存放没有处理的任务,提供一个缓冲机制
什么时候使用线程池
线程所需时间
创建时间 T1
服务时间 T2
销毁时间 T3
当 T1+T3 》 T2 使用线程池
实现线程池的方法
1 ---Executors.newCachedThreadPool()
创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用
2 ---Executors.newFixedThreadPool (int nThreads) (常用)
创建一个有固定数量线程的线程池
例子 :每隔一秒输出一次当前线程的名字,总计输出5次,创建一个线程池,该线程池中创建两个线程,
使线程池执行3次步骤一的任务
----------------------------------------------------------------------------------------------------------------
结果:
由于线程的通信中的生产者- 消费者模型 每次都要放馒头,取馒头 ,唤醒线程,等待线程,效率时间方面会差些,
用BlockingQueue 队列 可以解决这一问题。
ArrayBlokingQueue:(阻塞队列) 相关方法:
1、add(Object):将Object加入到队列中,如果队列可以容纳,则返回true,否则抛出异常
2、offer(Object):表示如果可能的话,将Object加入到队列中,如果能放进去,返回true,否则返回false
3、put(Object):将Object加入到队列中,如果队列没有空间,调用此方法的线程被阻塞直到队列中有空间再继续(一般用)
4、poll(time):取走队列中排在首位的元素对象,如果队列为空,则可以等待给定的time时间,取不到元素,返回null
5、take():取走队列中首位元素对象,如果队列为空,把调用该方法的线程阻塞。直到有元素加入到队列。(一般用)
这里给个例子,馒头换成苹果,其他一致。
------------------------------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------
输出:
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- Python3写爬虫(四)多线程实现数据爬取
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序