欢迎来到茶色岛的神秘岛屿,在这里你将收获Java多线程的奥秘
活动地址:CSDN21天学习挑战赛
学习的最大理由是想摆脱平庸,早一天就多一份人生的精彩;迟一天就多一天平庸的困扰。各位小伙伴,如果您:
想系统/深入学习某技术知识点…
一个人摸索学习很难坚持,想组团高效学习…
想写博客但无从下手,急需写作干货注入能量…
热爱写作,愿意让自己成为更好的人…
…
欢迎参与CSDN学习挑战赛,成为更好的自己,请参考活动中各位优质专栏博主的免费高质量专栏资源(这部分优质资源是活动限时免费开放喔~),按照自身的学习领域和学习进度学习并记录自己的学习过程。您可以从以下3个方面任选其一着手(不强制),或者按照自己的理解发布专栏学习作品,参考如下:
前言
一、基本概念:程序、进程、线程
1.程序(program):
2.进程(process)
3.线程(thread)
二、线程的创建和使用
1.Thread类
2.API 中创建 线程的两种方式
三、线程的生命周期
四、线程的同步
1.问题的原因:
2. 解决办法:
3.具体实现方法:
4.同步机制中的锁
5.释放锁的操作
6.不会释放锁的操作
五、线程的通信
六、JDK5.0新增线程创建方式
1.新增方式一:实现Callable 接口
2.新增方式二:使用线程池
总结
让天下没有难学的技术。
Hello,大家好✋✋,我是茶色岛,一位已经在csdn呆了将近一年的博主,本篇文章将为大家讲解Java多线程,希望会对你们有所帮助,同时也希望可以收获大家的喜爱,点个关注,谢谢大家。
为完成特定任务、用某种语言编写的一组指令的集合。
即指一段静态的代码,静态对象
是程序的一次执行过程,或是正在运行的一个程序。
是一个动态的过程:有它自身的产生、存在和消亡的过程
进程可进一步细化为线程,是一个程序内部的一条执行路径
何时需要多线程
程序运行多个线程通过java.lang.Thread类来体现
构造器
- Thread() :创建新的Thread对象
- Thread(String threadname): :创建线程并指定线程实例名
- Thread(Runnable target) :指定创建线程的目标对象,它实现了Runnable接口中的run方法
- Thread(Runnable target, String name) :创建新的Thread对象
方式一: 继承Thread类
1) 定义子类继承Thread类。
2) 子类中重写Thread类中的run方法。
3) 创建Thread子类对象,即创建了线程对象。
4) 调用线程对象start方法:启动线程,调用run方法。
方式二:实现Runnable 接口
1) 定义子类,实现Runnable接口。
2) 子类中重写Runnable接口中的run方法。
3) 通过Thread类含参构造器创建线程对象。
4) 将Runnable接口的子类对象作为实际参数传递给Thread类的构造器中。
5) 调用Thread类的start方法:开启线程,调用Runnable子类接口的run方法。
Thread 类的有关方法
- void start(): 启动线程,并执行对象的run()方法
- run(): 线程在被调度时执行的操作
- String getName(): 返回线程的名称
- void setName(String name):设置该线程名称
- static Thread currentThread(): 返回当前线程。在Thread子类中就
- 是this,通常用于主线程和Runnable实现类
- static void yield(): : 线程让步(暂停当前正在执行的线程,把执行机会让给优先级相同或更高的线程,若队列中没有同优先级的线程,忽略此方法)
- join() : 当某个程序执行流中调用其他线程的 join() 方法时,调用线程将被阻塞,直到 join() 方法加入的 join 线程执行完为止(低优先级的线程也可以获得执行)
- static void sleep(long millis) :(指定时间:毫秒)令当前活动线程在指定时间段内放弃对CPU控制,使其他线程有机会被执行,时间到后重排队。抛出InterruptedException异常
- stop(): 强制线程生命期结束,不推荐使用
- boolean isAlive(): : 返回boolean,判断线程是否还活着
当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,另一个线程参与进来执行。导致共享数据的错误。
对多条操作共享数据的语句,只能让一个线程都执行完,在执行过程中,其他线程不可以
参与执行。
1.使用Synchronized维持线程同步
1. 同步代码块 :
synchronized ( 对象){
// 需要被同步的代码;
}
2. synchronized 还可以放在方法声明中,表示 整个 方法为 同步方法 。
例如:
public synchronized void show (String name){
….
}
2.使用 Lock( 锁)维持线程同步
class A{
private final ReentrantLock lock = new ReenTrantLock();
public void m(){
lock.lock();
try{
// 保证线程安全的代码;
}
finally{
lock.unlock();
}
}
}
synchronized 与 Lock 的对比
1.Lock是显式锁(手动开启和关闭锁,别忘记关闭锁),synchronized是
隐式锁,出了作用域自动释放
2. Lock只有代码块锁,synchronized有代码块锁和方法锁
3. 使用Lock锁,JVM将花费较少的时间来调度线程,性能更好。并且具有
更好的扩展性(提供更多的子类)
优先使用顺序:
Lock -> 同步代码块(已经进入了方法体,分配了相应资源) ->同步方法(在方法体之外)
- 当前线程的同步方法、同步代码块执行结束。
- 当前线程在同步代码块、同步方法中遇到break、return终止了该代码块、该方法的继续执行。
- 当前线程在同步代码块、同步方法中出现了未处理的Error或Exception,导致异常结束。
- 当前线程在同步代码块、同步方法中执行了线程对象的wait()方法,当前线程暂停,并释放锁
- 线程执行同步代码块或同步方法时,程序调用Thread.sleep()、Thread.yield()方法暂停当前线程的执行
- 线程执行同步代码块时,其他线程调用了该线程的suspend()方法将该线程挂起,该线程不会释放锁(同步监视器)。应尽量避免使用suspend()和resume()来控制线程
执行wait() 与 与 notify() 和 和 notifyAll()
wait() 方法
- 在当前线程中调用方法: 对象名.wait()
- 使当前线程进入等待(某对象)状态 ,直到另一线程对该对象发出 notify(或notifyAll) 为止。
- 调用方法的必要条件:当前线程必须具有对该对象的监控权(加锁)
- 调用此方法后,当前线程将释放对象监控权 ,然后进入等待
- 在当前线程被notify后,要重新获得监控权,然后从断点处继续代码的执行
notify()/notifyAll()
- 在当前线程中调用方法: 对象名.notify()
- 功能:唤醒等待该对象监控权的一个/所有线程。
- 调用方法的必要条件:当前线程必须具有对该对象的监控权(加锁)
线程池相关API:ExecutorService 和 Executors
以上就是今天要讲的java线程,本文仅仅简单介绍了线程的基础知识。
长路漫漫,希望我们一起努力。