多线程
概念
程序
为了完成某个任务或功能,选择某个编程语言而编写的一组代码指令的集合
进程
程序的一次运行,是操作系统管理和调度的最小单位,每一个进程之间内存是相互独立的,如果进程之间要通信比较麻烦,可以通过文件,或网络通信方式等
线程
是进程中的其中一条执行路径,是CPU调度任务的最小单位
线程是共享同一个进程的内存
如何开启主线程以外的线程
方式一:继承java.lang.Thread类
①继承Thread类
②重写public void run(){}编写线程体,即该线程需要完成的任务代码
③创建线程对象
④启动线程:线程对象.start();
方式二:实现java.lang.Runnable接口
①实现java.lang.Runnable接口
②实现public void run(){}编写线程体,即该线程需要完成的任务代码
③创建线程对象
④启动线程:借助Thread类的对象new Thread(自定义线程对象).start();
两种方式的区别
区别:
(1)继承Thread类会有单继承的限制 实现Runnable接口不会有单继承的限制
(2)继承Thread类的方式,共享数据方面比较麻烦,使用static方式 实现Runnable接口,共享数据时,只需要共用同一个的Runnable接口的实现类的对象即可
(3)继承Thread类的方式,同步的锁的选择要么选择一个static对象作为锁,要么选择“类名.class即当前类Class对象” 实现Runnable接口,同步锁可以直接选择this对象
线程安全问题
前提条件
(1)有多个线程
(2)共享数据
(3)多条语句操作共享数据
解决方法
同步synchronized
形式
//同步代码块 synchronized(锁对象){ 同步代码,即需要加锁的代码 } //同步方法 synchronized [修饰符] 返回值类型 方法名(形参列表)抛出的异常列表
同步锁
(1)任意类型的对象
(2)保证使用共享数据的多个线程,共用同一个锁对象
锁的范围 同步代码块:范围
(1)不能太大:机会不均匀
(2)不能太小:安全问题没解决
(3)最好锁一次任务代码
同步方法的锁:
静态方法的锁:当前类的Class对象,即当前类名.class 非静态方法的锁:当前对象,this
线程通信
问题:生产者消费者问题
问题 现象描述
有多个线程共享一个缓冲区(例如:数据仓库,文件等),有的线程往里放数据,有的线程往外取数据
问题有两个
问题:线程安全问题 因为有共享数据 如何解决:同步
问题:缓冲区大小有限的 如何解决:线程通信
线程通信的方法
(1)wait()
(2)notify()和notifyAll()
在java.lang.Object 为什么
线程通信依赖于锁对象,即wait()和notify()是由锁对象调用
锁对象可能是任意类型的对象,那么这些方法只能在Object类中声明
面试题:wait()和sleep()的异同?
同 这两个方法都会导致当前线程从运行状态到阻塞状态
不同
从阻塞回到就绪状态
sleep()睡眠时间到了
wait()也可以设置时间,但更多时候是通过notify()
声明的类不同
wait是Object中,非静态方法
sleep是Thread类中,静态方法
锁释放问题
sleep:不会释放锁的 例如:在卫生间睡着了,锁还在手上
wait():会释放锁的 例如:抢到锁了,但是因为一些条件不满足,就释放锁,由其他线程执行
java.lang.Thread
方法
1、获取线程名称的方法 getName()
2、获取当前线程对象 Thread.currentThread()
3、线程休眠 Thread.sleep(毫秒) Thread.sleep(毫秒,纳秒)
4、线程的优先级
getPriority()
setPriority()
优先级的范围是1-10
MAX_PRIORITY:10
MIN_PRIORITY:1
NORMAL_PRIORITY:5
注意:业务逻辑不能依赖于优先级
5、加塞
join() 这句代码写在那个线程体中,哪个线程被加塞,被调用这个join()的线程加塞
6、run():所有线程都要写
7、start():启动线程
生命周期
标签:同步,Thread,对象,Runnable,sleep,线程,多线程 From: https://www.cnblogs.com/woniupa/p/17183667.html