JAVA进阶
学习10.0
IDEA与多线程
多线程
基本概念
1、程序
指一段静态的代码
2、进程
正在运行的一段程序
3、线程
一个程序内部的一个执行路径,
4、单核CPU和多核CPU
java程序至少有三个线程:main()主线程,gc()垃圾回收线程,异常处理线程
5、并行与并发
并行:多个CPU同时执行多个任务
并发:一个CPU同时执行多个任务
*创建和使用(4种)
1、方法一:通过:java.lang.Thread
类
步骤:
继承于Thread类;
重写Thread类的run()方法;
创建Thread类的子类的对象;
通过此对象调用start。
注意
>不能直接调用run
>不可以让已经start()的线程再启动一次,只能再创建一个对象去start()
Thread类的常用方法
start();
run();
currentThread();静态方法,返回执行当前代码的线程
getName();
setName();
yield();释放当前cpu的执行权
join();
stop();强制结束
sleep(long milllitime);指定当前线程睡眠多少ms
2、方法二:通过:实现Runnable接口
步骤:
创建一个实现类Runnable接口的类;
实现类去实现Runnable中的抽象方法;
创建实现类的对象;
将此对象作为以参数传递到thread类的构造器中,创建Thread类的对象;
通过Thread类的对象调start();
方法一和方法二的比较
>开发中优先选择实现Runnable接口方法
实现方式没有单继承的局限性
适合实现有共享数据的
>相同点:重写run();调start();
3、方法三:实现Callable方法 (jdk5.0新增)
步骤:
创建实现Callable方法的实现类
实现Call方法,将此线程需要执行的操作声明在call()中
创建Callable接口实现类的对象
将此接口实现类的对象作为传递到FutureTask构造器中,创建FutureTask的对象
将FutureTask的对象作为参数传递到Thread类的构造器中,创建Thread对象,并调用start();
获取callable方法中的返回值
如何理解实现Callable方法比前一种方法强大?
call方法可以有返回值;可以抛出异常;
Callable是支持泛型的
4、方法四:使用线程池
步骤:
提供指定线程数量的线程池
执行指定的线程的操作,需提供Runnable或Callable接口实现类的对象
关闭连接池
优先级的设置
MAX_PRIORITY:10
MAX_PRIORITY:1
NORM_PRIORITY:5 (默认优先级)
如何设置优先级?
setPriority(int p):
getPriority();
高优先级抢占低优先级cpu执行权,只是概率高,不是必须
线程的生命周期
要经历五种状态:
新建:
就绪:
阻塞:sleep(long time); join(); 等待同步锁; wait(); suspend();
运行:
死亡:
关注:状态1—>状态2,哪些方法执行了
*线程的同步(3种)
通过同步机制,解决线程的安全问题
方式一:同步代码块
synchronized(同步监视器){
//需要被同步的代码(操作共享数据的代码)
}
说明:同步监视器,俗称:锁。任何一个类的对象,都可以充当锁。
要求:多个线程必须要共用同一把锁
操作同步时代码时,只能有一个线程参与,其他线程等待
在实现Runnable接口创建多线程时,可以考虑this充当监视器
在继承Thread中,要慎用this,可以考虑当前类
方式二:同步方法
如果操作共享数据的代码完整的声明在一个方法中,可将这个方法声明为同步的
仍然涉及到同步监视器,只是不需声明
非静态的同步方法,是this;
静态的同步方法,是当前类本身
死锁:
方式三: Lock锁
synchronized vs lock 区别?
synchronized在执行完相应的同步代码后,自动的释放同步监视器
lock需要手动启动,手动结束
线程的通信
wait();当前线程进入阻塞状态
notify();唤醒被wait的一个线程
notifyAll();唤醒被wait的所有线程
---------使用前提:
必须使用在同步方法或同步代码块中;
前面省略的是this.
调用者必须是同步方法或同步代码块中的同步监视器
sleep和wait的异同?
都可以使当前进程进入阻塞状态
声明位置不同:Thread类中声明sleep;Object中声明wait;
调用要求不同:sleep可以在任何场景,wait必须在同步代码块中
关于是否释放同步监视器:若都用在同步方法和同步代码块中,sleep不会释放锁,wait会