目录
笔记包含
1 |
线程概念:程序,进程,线程 |
2 | 线程的创建和使用 |
3 | 线程的生命周期 |
4 | 线程的同步 |
5 | 线程的通讯 |
6 | JDK5.0新增线程创建方式 |
线程概念:程序,进程,线程
CPU单核多核运算,并发与并行
单核CPU和多核CPU的理解
并行与并发
多线程的优点
背景:
以单核CPU为例, 只使用单个线程先后完成多个任务(调用1多个方法),肯定比用多个线程来完成用的时间更短,为何仍需多线程呢?
多线程的优点:
1.提高应用程序的响应。对图形化界面更有意义,可增强用户体验。
2.提高计算机系统CPU的利用率
3.改善程序结构。将既长又复杂的进程分为多个线程,独立运行,利于理解和修改
何时用到多线程
1.程序需要同时执行两个或者多个任务。
2.程序需要实现一些需要等待的任务时,如用户输入,文件读写操作,网络操作,搜索等。
3.需要一些后台运行的程序时。
多线程的创建
多线程的创建方式一:继承Thread
步骤:
1.创建一个类继承于“Thread”
2.这个子类中重写run方法
(方法体写想要执行的代码—运行的分线程)
3.创建子类对象
4.子类对象调用父类方法:子类对象.start();
—启动当前线程的同时调用此对象的run方法
例:分线程遍历1-100以内的偶数
输出结果(部分)
说明:
//想要创建多线程,需要创建多个对象,不同对象调用.start();既开启多线程。
可以使用匿名对象写法:
线程的创建方式二:实现Runnable接口
步骤
1.实现类实现runnable接口
2.实现runnable接口中的run’方法
3.创建实现类对象
4.将实现类对象作为参数创建Thread对象–参数相当于Thread调用的方法
5.Thread对象调用start方法
例:分线程遍历1-100以内的偶数
输出结果(部分)
线程的创建方式之三:实现callable
创建步骤
* 1.实现类实现callable
* 2.重写call方法
* 3.创建创建实现类对象
* 4.将实现类对象作为参数传递到FutureTask构造器创建FutureTask对象
*5. 启动线程—》创建一个参数为FutureTask的Thread对象
* —-new Thread(FutureTask对象).start
*( —-FutureTask也实现了Runnable所以可以放入)
* 6调用FutureTask的get方法
(以下方法可以不调用,如果关心返回值就调用, //以下还可以捕获call方法抛出的异常)
——- Object 变量 =FutureTask对象.get();
变量.sout
(try-catch处理)
例:分线程遍历1-100以内的偶数,并且返回累加总和
输出结果(部分)
如何解释callable比runnable强大
1.callable可以有返回值
2.callable可以捕获重写的call方法抛出异常,在外面的操作处理。
3.callable支持泛型
线程的命名方式
1.子类对象.setname(“”);
2.Thread.currentThread().setname(“”);
3.通过构造器改名:
Public 任意名(Stirng name){
Super(name);
}
线程的常用方法
线程的调度
通过时间片轮转
抢占式:高优先级的线程抢占CPU
JAVA调度方法
1.同优先级线程组成先进出队列(先到先服务),使用时间片策略
2.对高优先级,使用优先调度的抢占式策略
线程优先级 priority
优先级说明:
高优先级的线程要抢占优先级低的线程的CPU的执行权,但是只是从概率上讲,高优先级的线程高概率的情况下被执行,并不意味着只有当高优先级的线程执行完以后,优先级低的线程才执行。
线程的生命周期
线程的同步—解决线程的安全问题
例子:创建三个窗口卖票,总票数为100(使用实现Runnable接口方式)
输出结果(部分):
1.问题:卖票过程中,出现了重票,错票 – – >说明出现了线程的安全问题
2.问题出现的原因:当某个线程操作车票的过程中,尚未操作完成时,其他线程参与进来
也操作车票,使多个线程同时访问统一数据出现问题。
3.如何解决:当一个线程a在操作tickt(票)的时候,其他线程不能参与进来。直到线程a操作完tickt,其他线程才可以操作tickt,这种情况即使a出现了阻塞,也不能够被改变。
JAVA中通过同步来解决线程安全问题
方式一:同步代码块 synchronized
synchronized(同步监视器){
//需要被同步的代码
}
说明:1.操作共享数据的代码,即为需要被同步的代码
2.共享数据:多个线程共同操作的变量。比如:tickt就是共享数据
3.同步监视器,俗称:锁。 任何一个类的对象,都可以充当锁。
要求:多个线程必须共同一个锁
例子:多个线程同时操作tickt
输出结果(部分):
方式二:同步方法
在方法创建时声明为:synchronized
何时使用:当操作共享数据的完整代码声明在方法中时
补充说明:1.在实现Runnable接口创建多线程的方式中,我们可以考虑this充当同步监视器。
2. 同步的方式:虽然解决了线程的安全问题,但是操作同步代码时,只能有一
个线程参与,其他线程等待。相当于是一个单线程的过程,效率低下。
方式三 :Lock(锁)
Lock的使用演示
Lock和synchronized的区别:
相同:两者都可以解决线程安全的问题
不同:synchronized机制在执行完相应的同步代码块以后,自动的释放同步监视器
Lock需要手动的启动同步(Lock() ),同时结束也需要手动的实现(unlock() )
Lock和synchronized的使用优先顺序
Lock – – >同步代码块(已经进入了方法体,分配了相应资源)- – >同步方法(在方法体之外)
线程的死锁问题
线程的通信
wait(阻塞)—notify(释放)
使用:两个线程的交替打印(线程a打印完成后进入阻塞状态并唤醒线程b,循环进行)
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/154593.html