什么是多线程?
多线程就是一个程序中同时执行的多个顺序流(就是一个程序中同时运行多段代码)
如何创建一个线程?
第一种方式:
线程类:这个类中的代码可以作为一个顺序流(线程)单独的运行
特性 : 需要实现Runnable接口
如果一个类实现了Runnable接口,那么这个类中的代码就可以作为一个单独的线程来运行;
我们要想把这个类中的代码作为一个线程来运行:
① 这个类要实现Runnable接口,重写run方法;
② 创建这个类(Runnable)对象;
③ 根据这个Runnable对象创建线程;
④ 启动线程。
实例:
/**
* 当我们这个类实现了Runnable借口,我们这个类就变成了线程类
* 这个类中的代码就可以作为单独的顺序流来执行
* 当我们启动了这个线程后,这个顺序流就从run方法中的第一句代码执行
* run方法就是一个线程入口
*/
@Override
public void run() {
for(int i=0;i<100;i++){
System.out.println("<>"+i);
}
}
public static void main(String[] args) {
//根据TextThead线程类创建一个线程,然后启动这个线程
//创建Runnable对象
Runnable r=new TextThread();
//根据这个对象来创建一个线程
Thread t=new Thread(r);
//启动线程:通过Thread中的start()方法启动线程
t.start();
for(int i=0;i<100;i++){
System.out.println("------"+i);
}
}
创建线程的第二种方式:(//重写父类方法:右键--->source-->override/implements method)
① 创建一个类继承Thread—重写run方法,实现Runnable类;
② 创建这个类的对象,这个对象本身就是线程;
③ 通过这个对象调用start方法启动线程,就会以单独的线程的形式执行当前类的run方法。
当我们使用线程对象调用start方法之后,实际上并没有立即开始执行,它指的是让当前线程进去到“可运行状态”--------值得是这个线程可以运行,但是还没有运行
注意:不要直接在程序中调用run()方法!
状态变化:
两种线程创建方式的比较:
使用Runnable接口
可以将CPU,代码和数据分开,形成清晰的模型;
还可以从其他类继承;
保持程序风格的一致性。
直接继承Thread类
不能再从其他类继承;
编写简单,可以直接操纵线程,无需使用Thread.currentThread()。
线程结束的方式:
运行结束-----抛出异常结束---手动结束
线程到达其 run() 方法的末尾;抛出一个未捕获到的 Exception 或 Error;
方法 说明
start() 新建的线程进入Runnable状态
run() 线程进入Running 状态
wait() 线程进入等待状态,等待被notify,这是一个对象方法,而不是线程方法
notify()/
notifyAll() 唤醒其他的线程,这是一个对象方法,而不是线程方法
yield() 线程放弃执行,使其他优先级不低于此线程的线程有机会运行,它是一个静态方法
getPriority()/setPriority() 获得/设置线程优先级
sleep() 线程睡眠指定的一段时间
join() 调用这个方法的主线程,会等待加入的子线程完成
线程可以分为‘守护线程’和‘用户线程’:
//用户线程:当用户线程执行结束后,无论其他的线程是否执行结束,这个用户线程都会停止
//守护线程:为用户线程提高服务,直到最后一个用户线程执行结束后才结束守护线程
//作为一个用户线程,无论需要花多长执行时间,只要不出现异常,最后都要把代码执行结束
//作为一个守护线程,无论有多少代码,无论代码是否执行结束,只要用户线程都结束了,守护线程也会停止执行
//main方法是默认的守护线程
//我们直接创建的线程默认是‘用户线程’
//我们可以通过setDeamon(true)方法将一个用户线程设置为守护线程
//我们可以通过setDeamon(false)方法将一个守护线程设置为用户线程
//我们还可以通过isDeamon()方法判断某个线程是否是守护线程
线程的名字:
我们创建的每一个线程都是有线程名的,默认线程名:Thread-n
我们也可以为创建的线程命名
线程的优先级:
//线程的优先级:分为1-10 共十个级别
//数值越大,优先级越高
//我们在没有设置优先级的情况下,默认级别为5
//线程优先级高,并不代表优先级低的就不执行,只让优先级高的执行;
//在单位时间内,优先级高的线程能够有更多的执行机会,优先级低的也有机会执行,只是机会更少
//获取当前线程的优先级---getPriority()方法
//System.out.println(t1.getPriority());
//setPriority()设置当前线程优先级
t1.setPriority(1);
t2.setPriority(10);
Join方法:
Thread API 包含了等待另一个线程完成的方法:join() 方法。当调用 Thread.join() 时,调用线程将阻塞,直到被join方法加入的目标线程完成为止。
Thread.join() 通常由使用线程的程序调用,以将大问题划分成许多小问题,每个小问题分配一个线程。当所有的小问题都得到处理后,再调用主线程来进一步操作。
try {
//创建一个线程并启动
Myjoin1 j1=new Myjoin1();
Thread j2=new Thread(new Myjoin2());
j1.start();
j2.start();
//只保证当前线程不与j1线程竞争资源,也就是说只要j1线程执行结束了
//无论其他的线程执行的怎么样,main方法都会恢复执行,再与其他线程参与竞争资源
j1.join();
for (int i = 0; i < 100; i++) {
System.out.println("main"+i);
if(i==10){
//如果在main线程中调用了j.join()方法
//指的是让main线程处于休眠状态,直到被join的线程j执行结束后才恢复执行
j1.join();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
线程sleep()方法:延时当前线程时间,当前线程让出资源并且不参与竞争,当时间到了就结束休眠参与资源竞争!
public static void main(String[] args) {
try {
MyThread05 t5 = new MyThread05();
t5.start();
for (int i = 1; i <= 100; i++) {
System.out.println(i);
if(i==10){
//让当前线程休眠1ms,在休眠的这1ms之内,当前线程让出资源并且不参与竞争
//时间到了就结束休眠参与资源竞争
Thread.sleep(1);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
线程的wait()方法:
如果某个线程调用了wait方法,那么这个线程就会处于休眠状态,直到有其他线程调用notify或者notifyAll方法适合才能唤醒此线程,此线程才能接着执行!
多线程的数据共享:
当多个线程同时访问同一个对象(数据)时候,因为线程执行顺序的不确性,有可能倒置数据的错误
解决方法:当某一个线程在访问公用对象(数据)的时候,对这个数据进行锁定,锁定之后的其他线程如果想要访问这个数据,就必须等待该线程释放这数据
在某些线程执行过程中,可能有多个步骤必须连接执行(文件拷贝/银行取款问题)
Synchronized关键字:对某一个线程进行锁定,锁定之后其他线程就不能访问资源数据了!
互诉锁:
在Java语言中,引入了对象互斥锁(mutual exclusive lock,也简称为对象锁)的概念,来保证共享数据操作的完整性:
每个对象都对应于一个可称为“互斥锁”的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象。
关键字synchronized 来与对象的互斥锁联系。当某个对象用synchronized修饰时,表明该对象在任一时刻只能由一个线程访问。
对多个线程同时对某一个方法(资源)同时调用时候,synchronized关键字:
修饰方法名/锁定方法的调用者(对象)
①此时表示只能被一个线程访问,对其他正在运行的线程如果有访问这个数据方法时候就处于等待状态,直到当前线程释放对象的锁(代码执行结束)才能访问;对其他没有访问这个方法数据的线程则不受影响。
②如果多个方法都添加了关键字,并且都使用到相同的当前类对象(通过相同的对象调用不同的方法),这多个方法就不能同时执行,如果调用的第一个方法线程开始执行了,其他的方法线程就只能处于等待状态,当这个方法执行结束后,其他的方法才能竞争执行权
*同一个对象就是一个人只能做一件事。
*不同对象就是两个人各做各得事情。
在Java中的两种使用synchronized的方式:
放在方法前面,这样,调用该方法的线程均将获得对象的锁。
放在代码块前面,它也有两种形式:
synchronized (this){… …}或synchronized {… …}:代码块中的代码将获得当前对象引用的锁
synchronized(otherObj){… …}:代码块中的代码将获得指定对象引用的锁
释放锁:
如果一个线程一直占用一个对象的锁,则其他的线程将永远无法访问该对象,因此,需要在适当的时候,将对象锁归还。
当线程执行到synchronized()块结束时,释放对象锁。
当在synchronized()块中遇到break, return或抛出exception,则自动释放对象锁。
当一个线程调用wait()方法时,它放弃拥有的对象锁并进入等待队列。
死锁:
是指两个线程,都相互等待对方释放lock
是不可测知或避开的
应采取措施避免死锁的出现
常用方法:notify()Wait()notifyAll()Thread.interrupt()
Object 类定义了 wait()、notify() 和 notifyAll() 方法。可以让线程相互通知事件的发生。要执行这些方法,必须拥有相关对象的锁。
wait() 会让调用线程休眠,直到用 Thread.interrupt() 中断它、过了指定的时间、或者另一个线程用 notify() 或 notifyAll() 唤醒它。
当对某个对象调用 notify() 时,如果有任何线程正在通过 wait() 等待该对象,那么就会唤醒其中一个线程。当对某个对象调用 notifyAll() 时,会唤醒所有正在等待该对象的线程。
- 大小: 18.5 KB
- 大小: 44.5 KB
- 大小: 31.8 KB
分享到:
相关推荐
Java多线程是Java编程语言中一个非常重要的概念,它允许开发者在一个程序中创建多个执行线程并行运行,以提高程序的执行效率和响应速度。在Java中,线程的生命周期包含五个基本状态,分别是新建状态(New)、就绪...
### Java多线程操作数据库:深入解析与应用 在当今高度并发的应用环境中,Java多线程技术被广泛应用于处理数据库操作,以提升系统的响应速度和处理能力。本文将基于一个具体的Java多线程操作数据库的应用程序,深入...
Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式...
Java多线程是Java编程中的重要概念,它允许程序同时执行多个任务,极大地提升了程序的效率和性能。在Java中,实现多线程有两种主要方式:通过实现Runnable接口或者继承Thread类。本案例将深入探讨Java多线程中的关键...
Java多线程是Java编程中的一个重要概念,它允许程序同时执行多个任务,提高了程序的效率和响应速度。在Java中,实现多线程有两种主要方式:继承Thread类和实现Runnable接口。 1. 继承Thread类: 当我们创建一个新...
Java多线程是Java编程中的重要概念,尤其在如今的多核处理器环境下,理解并熟练掌握多线程技术对于提高程序性能和响应速度至关重要。本资料详细讲解了Java多线程的原理,并提供了丰富的实战代码,非常适合Java初学者...
### Java多线程分页查询知识点详解 #### 一、背景与需求分析 在实际的软件开发过程中,尤其是在处理大量数据时,如何高效地进行数据查询成为了一个关键问题。例如,在一个用户众多的社交平台上,当用户需要查看...
《汪文君JAVA多线程编程实战》是一本专注于Java多线程编程的实战教程,由知名讲师汪文君倾力打造。这本书旨在帮助Java开发者深入理解和熟练掌握多线程编程技术,提升软件开发的效率和质量。在Java平台中,多线程是...
java多线程PPT 多线程基本概念 创建线程的方式 线程的挂起与唤醒 多线程问题
Java多线程读大文件 java多线程写文件:多线程往队列中写入数据
Java多线程机制是Java编程中至关重要的一部分,它允许程序同时执行多个任务,提升应用程序的效率和响应性。以下是对各个知识点的详细说明: 9.1 Java中的线程: Java程序中的线程是在操作系统级别的线程基础上进行...
在本文中,我们将深入浅出Java多线程编程的世界,探索多线程编程的基本概念、多线程编程的优点、多线程编程的缺点、多线程编程的应用场景、多线程编程的实现方法等内容。 一、多线程编程的基本概念 多线程编程是指...
在Java编程中,多线程并发是提升程序执行效率、充分利用多核处理器资源的重要手段。本文将基于"java 多线程并发实例"这个主题,深入探讨Java中的多线程并发概念及其应用。 首先,我们要了解Java中的线程。线程是...
《JAVA多线程教学演示系统》是一篇深入探讨JAVA多线程编程的论文,它针对教育领域中的教学需求,提供了一种生动、直观的演示方式,帮助学生更好地理解和掌握多线程技术。这篇论文的核心内容可能包括以下几个方面: ...
本项目以"java多线程实现大批量数据导入源码"为题,旨在通过多线程策略将大量数据切分,并进行并行处理,以提高数据处理速度。 首先,我们需要理解Java中的线程机制。Java通过`Thread`类来创建和管理线程。每个线程...
综上所述,"java多线程查询数据库"是一个涉及多线程技术、线程池管理、并发控制、分页查询等多个方面的复杂问题。通过理解和掌握这些知识点,我们可以有效地提高数据库操作的效率和系统的响应速度。
《Java多线程编程实战指南》这本书深入浅出地讲解了Java多线程的核心概念和实战技巧,分为核心篇和设计模式篇,旨在帮助开发者掌握并应用多线程技术。 1. **线程基础** - **线程的创建**:Java提供了两种创建线程...
这份“JAVA多线程编程技术PDF”是学习和掌握这一领域的经典资料,涵盖了多线程的全部知识点。 首先,多线程的核心概念包括线程的创建与启动。在Java中,可以通过实现Runnable接口或继承Thread类来创建线程。创建后...
Java多线程编程是Java开发中的重要组成部分,它允许程序同时执行多个任务,极大地提高了程序的效率和响应性。在Java中,多线程主要通过继承Thread类或实现Runnable接口来实现。本教程《Java多线程编程核心技术》将...
Java多线程编程实战指南(核心篇) 高清pdf带目录 随着现代处理器的生产工艺从提升处理器主频频率转向多核化,即在一块芯片上集成多个处理器内核(Core),多核处理器(Multicore Processor)离我们越来越近了――如今...