一、开一个线程的方式 :
1.继承 Thread
2. 实现 Runnable 接口(常用)
为什么实现 Runnable 接口可以,因为Thread类里面的run方法,先对target判空,target是Runnable类,可以在Thread构造方法传入
3.实现Callable接口
区别:1.重写call,可以进行返回值
2.需要开线程池,把实现Callable的子类作为参数,执行线程池的submit开启线程
3.关闭线程池,区别:Callable能抛异常
总结:线程start的时候,不会立即执行,cpu分配,主线程和分线程交替执行,直至执行所有内容
二、
1).线程的方法
1.setPriority(int newPriority):更改线程的优先级,getPriority():获取优先级
1.1 线程的优先级用数字表示,范围1-10
1.2 Thread.MIN_PRIORITY=1;Thread.MAX_PRIORITY=10;Thread.NORM_PRIORITY=5;
1.3 优先级低意味着获取CPU的调度低,并不意味着顺序调用
2.static void sleep(long millis):在指定的毫秒数让当前线程休眠
2.1 可以放大问题,用来定义并发问题
2.2 线程的静态方法 Thread.sleep:对当前线程进行休眠
2.3 sleep不是释放锁
2.4 模拟倒计时
2.3 每隔一秒打印系统当前时间
3.void join():等待该线程终止
3.1 线程的方法 thread.join()
3.2 可以理解为插队,等该线程执行完,才执行其他线程
4.static void yield():暂停当前正在执行的线程对象,并执行其他线程(让2线程程重回起跑线)
4.1 线程的方法:Thread.yield();
4.2 以下是礼让没有成功的情况,大多数是成功的
5.void interrupt():中断线程,别用这种方式
6.bollean isAlive():测试线程是否处于活动状态
7.Thread.state( 线程的五种状态) getState():观测线程状态
7.1 线程的方法:Thread.getState()
2)停止线程
1.不推荐使用jdk提供的stop和destroy方法(已废弃)
2.推荐使用一个标志位进行终止变量,当flag=false,则终止线程运行
3)线程的额外概念
1. 线程分为用户线程和守护线程
2. 虚拟机必须确保用户线程执行完毕,不用等待守护线程执行完毕
3.守护线程用处:后台记录操作日志、监控内存、垃圾回收等待
4.线程的方法 thread.setDaemon(true):默认是false表示用户线程,正常的线程都是默认线程
5.例子
三、定时器
jdk1.5前的定时器
1.10s后执行一次
2.隔10s,后轮训3秒,都执行
3.Timer类的schedule()方法,第一个参数是timeTask类,执行内容;第二个参数可以是long:延迟多少毫秒执行,可以是Data,到具体的时间执行(一般是凌晨三点收邮件这种业务);第三个参数是long:周期,开轮训的效果
四、线程同步(处理并发问题)
1.处理并发问题的2个名词:队列和锁
2.synchronized:使用锁存在以下问题
2.1 一个线程持有锁会导致其他所有需要此锁的线程挂起
2.2 在多线程竞争下,加锁,释放锁会导致比较多的上下文切换和调度延时,引起性能问题
2.3 如果一个优先级高的线程等待一个优先级低的线程释放锁,会导致优先级导致,引起性能问题(例如:高优先级只想上小号,低优先级上大号,影响性能)