`

java多线程

阅读更多

什么是多线程?
多线程就是一个程序中同时执行的多个顺序流(就是一个程序中同时运行多段代码)
如何创建一个线程?
第一种方式:
线程类:这个类中的代码可以作为一个顺序流(线程)单独的运行
特性 : 需要实现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多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式...

    java多线程读取文件

    Java多线程读大文件 java多线程写文件:多线程往队列中写入数据

    java多线程ppt

    java多线程PPT 多线程基本概念 创建线程的方式 线程的挂起与唤醒 多线程问题

    java 多线程操作数据库

    一个java 多线程操作数据库应用程序!!!

    java多线程经典案例

    java多线程经典案例,线程同步、线程通信、线程阻塞等经典案例

    Java多线程编程技术

    《Java多线程编程核心技术》建议猿友们读两遍,因为其写得没有那么抽象,第一遍有些概念不是很理解,可以先跳过并记录起来,第一遍阅读的目的主要是了解整个架构。第二遍再慢慢品味,并贯穿全部是指点来思考,并将...

    Java多线程编程实战指南(核心篇)

    Java多线程编程实战指南(核心篇) 高清pdf带目录 随着现代处理器的生产工艺从提升处理器主频频率转向多核化,即在一块芯片上集成多个处理器内核(Core),多核处理器(Multicore Processor)离我们越来越近了――如今...

    Java多线程知识点总结

    该文档总结了Java多线程相关的知识点,分享给大家,简单易懂!

    java多线程的讲解和实战

    详细的讲解了java多线程的原理,并配有代码进行实战,适合java初学者和想对多线程有进一步了解的人。

    java多线程通信图解

    一张图方便理解和掌握java 多线程之间通信的实质 java 多线程 其实就是每个线程都拥有自己的内存空间,多线程之间的通信,比例A线程修改了主内存(main方法的线程)变量,需要把A线程修改的结果同步到主线程中,...

    java多线程处理数据库数据

    java多线程处理数据库数据,使用并发包,无框架,可批量处数据库数据,进行增删改。。等等操作。

    java多线程,对多线程,线程池进行封装,方便使用

    java多线程,对多线程,线程池进行封装,方便使用

    Java多线程编程经验

    现在的操作系统是多任务操作系统。多线程是实现多任务的一种方式。 线程是指进程中的一个执行流程,一个进程中可以运行多个线程。...本文档提供Java多线程编程经验,方便广大Java爱好者研究学习Java多线程

    java多线程处理大数据

    java多线程处理大数据,可根据配置的线程数,任务去调度处理

    java多线程并发

    java多线程并发的在新窗口

    Java多线程机制(讲述java里面与多线程有关的函数)

    Java多线程机制 9.1 Java中的线程 9.2 Thread的子类创建线程 9.3 使用Runable接口 9.4 线程的常用方法 9.5 GUI线程 9.6 线程同步 9.7 在同步方法中使用wait()、notify 和notifyAll()方法 9.8 挂起、恢复和终止线程 ...

    java多线程核心技术

    资深Java专家10年经验总结,全程案例式讲解,首本全面介绍Java多线程编程技术的专著 结合大量实例,全面讲解Java多线程编程中的并发访问、线程间通信、锁等最难突破的核心技术与应用实践 Java多线程无处不在,如...

    java多线程实现大批量数据导入源码

    java多线程实现大批量数据切分成指定份数的数据,然后多线程处理入库或者导出,线程的个数和每份数据的数量都可以控制

    java多线程查询数据库

    java多线程并发查询数据库,使用线程池控制分页,并发查询。

    java多线程模拟队列实现排队叫号

    java多线程模拟队列实现排队叫号,多线程模拟排队叫号取号 java多线程模拟队列实现排队叫号,多线程模拟排队叫号取号

Global site tag (gtag.js) - Google Analytics