多线程实现方式
Thread
继承Thread-->重写run()--->创建并且初始化对象--->对象名点start
class Demo{ public static void main(String[] args){ MutiThread aThread = new MutiThread(); aThread.start(); } } class MutiThread extends Thread{ @override public void run(){ System.out.println("这是一个线程"); } }
注意:
- 每个Thread对象就是一个线程
- 只有start以后线程才会开始运行,直接对象名点run()只是调用方法,并不是启动线程
- 启动多个对象需要创造多个Thread对象
Runnable
实现Runnable接口-->重写run()-->创建并且初始化对象--->创建Thread对象-->Thread对象名点start
class Demo{ public static void main(String[] args){ MutiRunnable aThread = new MutiRunnable(); Thread thread = new Thread(aThread); thread.start(); } } class MutiRunnable implements Runnable{ @override public void run(){ } }
注意:
- Runnable方式的多线程中,run()方法中的东西相当于任务,当创建了实现Runnable接口的对象时即为创建了任务,当再创建Thread对象时,就相当于将任务放在了线程中
callable
实现callable接口-->重写run()-->创建并实例化实现接口的类-->创建Thread对象-->Thread对象名点start
class Demo{ public static void main(String[] args){ MutiCallable aThread = new MutiCallable(); Thread thread = new Thread(MutiCallable); thread.start; } } class MutiCallable implements Callable{ @override public Object call(){ run 0; } }
控制api
休眠api --- sleep
sleep(long millis)使当前运行的程序停下来,数据类型为long,单位为毫秒
合并api---join
join()有三个重载的方法分别是
void | join() 等待这个线程死亡。 |
---|---|
void | join(long millis) 等待这个线程死亡最多 millis毫秒。 |
void | join(long millis, int nanos) 等待最多 millis毫秒加上 nanos纳秒这个线程死亡。 |
守护api ---daemon
void | setDaemon(boolean on) 将此线程标记为 daemon线程或用户线程。 |
---|---|
注意:
- 需要在线程启动前进行调用
- 当正在运行的线程都为守护线程时,JVM会退出虚拟机
礼让api---yeid
暂停当前正在进行的线程对象
注意:由于Java虚拟机采取的是抢夺类型的,所以当暂停当前的线程后,当前线程也会假如争抢的队列,有可能会再次强盗
中断api --- stop / interrupter
interrupter
不能真正的中断线程
stop
可以中断线程,但是存在安全性问题
数据安全问题
产生原因
多线程读取数据
非原子操作(原子操作:一个操作要么执行完,要么不执行)
解决办法
synchronized
synchronized(Object){ //需要上锁的的代码块 }
注意括号:
括号中可以是任意类对象,但是要和类中的成员变量统一
Java中的所有对象,都有一个标志位,来表示加锁和解锁的状态
加锁之后,当线程退出同步代码块时,JVM会自动清理标志位,使其变成未家所状态
lock
Lock lock = new ReentrantLock();//创建对象 lock.lock;//加锁 { //上锁代码块,大括号可以不要 } lock.unlock;//解锁
两种方法的区别:
- sychorinize不用创建对象,JVM隐式上锁解锁,lock需要创建对象,有完成的上锁和解锁操作d
- N久之前lock的效率要高于synchronized,但现在已经差不多了synchronized的
死锁
产生原因
两个线程的一部分必要资源都在对方手里的来进行下一步骤,从而导致程序阻塞
线程通信
- wait当前线程自我阻塞
- notify()唤醒一个阻塞的线程
- notifyAll()唤醒所有阻塞线程
线程池
ExecutorServer newCacheThreadPool()
- 会根据需要创建新的线程,也可以自动删除,60s处于空闲状态的线程
- 线程数量可以变,立马执行提交的异步任务(异步任务:在子线程中执行的任务)
ExecutorServer newFixedThreadPool()
- 线程数量固定(fixed:固定的)
- 维护一个无界队列(队列:先进先出),暂存已提交的来不及执行的任务
- 按照任务提交的顺序将任务执行完毕
ExecutorServer newSingleThreadExecutor()
- 单个线程
- 维护一个无界队列(队列:先进先出),暂存已提交的来不及执行的任务
- 按照任务提交的顺序将任务执行完毕