Java---进程
一、线程的基本概念
1、进程
概念:应用程序运行的时候进入到内存中,程序在内存中占用的内存空间(进程)
2、线程
线程:在内存和CPU之间,建立一条连接通路,CPU可以到内存中取出数据进行计算,这个链接的通路,就是线程
一个内存资源:一个独立的进程,进程中可以开启多个线程
并发:同一个时刻多个线程同时操作了同一个数据
并行:同一个时刻多个线程同时执行不同的程序
三级目录
二、Java实现线程的程序
1、java.lang.Thread类
实现线程程序的方法
1、定义类继承Thread类
2、子类重写方法run
3、创建子类对象
4、调用子类对象的方法start()启动线程
2、Thread类的方法
getName()返回线程名字,返回值是String类型
public class TheadName extends Thread{
public void run(){
}
}
public class getNameTest {
public static void main(String[] args) {
TheadName theadName = new TheadName();
System.out.println(theadName.getName());
}
}
静态方法:Thread currentThread()静态调用返回当前的线程对象
Thread thread = Thread.currentThread();
System.out.println(thread.getName());
join()方法:执行join()方法的线程,他不结束,其他线程运行不了
静态方法:static yield()线程让步,线程把执行权让出
3、java.lang.Runnable接口
实现线程程序的步骤
1、定义类实现接口
2、重写接口的抽象方法
3、创建Thread类对象
Thread类构造方法中,传递Runnable接口的实现类对象
4、调用Thread对象方法start()启动线程
三、线程安全
1、线程安全
线程安全:多线程操作一个资源,有可能出现安全问题
出现的原因:一个线程还没有结束,另一个线程就开始操作了
解决办法:
2、同步代码块
同步代码块可以解决线程安全问题:格式:synchronized ()关键字
synchronized (任意对象){
//线程操作的共享资源
}
任意对象:在同步中这个对象称为对象锁,简称锁(对象监视器)
同步代码块执行原理:
1、线程执行到同步时,判断锁是否存在
如果锁存在,获取到锁,进入到同步中执行
执行完毕,线程出去同步代码块,归还锁
2、线程执行到同步时,判断锁是否存在
如果锁不存在,线程只能在同步代码块外等待锁
3、同步方法
当一个方法中,所有代码都是线程操作的共享内容,可以在方法的定义上添加同步的关键字synchronized,同步的方法,或者称为同步的函数
同步方法中对象锁是this
静态同步方法中对象锁是:本类.class属性
四、JDK新特性Lock锁
JDK新特性:java.concurrent.locks包,定义了接口Lock
Lock接口代替了synchronized,可以更加灵活
Lock接口的方法
void lock()获取锁
void unlock()释放锁
Lock的实现类ReentrantLock
线程通信的方法wait(),notify()
1、方法的调用必须写在同步中
2、调用者必须是作为锁的对象
3、wait(),notify()为什么要定义在Object
同步中的锁,是任意对象,任意类都继承Object
wait()方法和sleep方法的区别
sleep在休眠的过程中,同步锁不会丢失,不释放
wait()等待时,发布监听器的所属权,释放锁,唤醒后要重新获取锁,才能执行
1、Lock接口的深入
Lock中的方法:newCondition()方法的返回值是接口Condition
Lock lock = new ReentrantLock();
Condition con1 = lock.newCondition();//返回Condition接口的实现类对象
Condition con2 = lock.newCondition();
Condition接口(线程的阻塞队列)
进入队列的线程,释放锁
出去队列的线程,再次的获取锁
接口的方法:await()线程释放锁进入队列
接口的方法:signal()线程出去队列,再次获取锁
2、Lock锁的实现原理
使用技术不开源,技术的名称叫做轻量级锁
使用的是CAS锁(Compare And Swap)自旋锁
JDK限制:当竞争的线程大于等于10,或者单个线程自旋超过10次的时候JDK强制CAS锁取消,升级为重量级锁(OS锁定CPU和内存的通信线路)
五、单例设计模式
要求:保证一个类的对象在内存中的唯一性
1、饿汉式
实现步骤:
私有构造器
自己创建对象封装
提供get方法,返回本类对象
public class Single {
//私有构造器
private Single(){}
//自己创建对象封装
private static Single single = new Single();
//提供get方法
public static Single getSingle(){
return single;
}
}
2、懒汉式
实现步骤:
私有修饰构造器
创建本类的成员变量,不new对象
方法get返回本类对象
public class Single02 {
//私有修饰构造器
private Single02(){}
//创建本类的成员变量,不new对象
private static Single02 s = null;
//方法get返回本类对象
public static Single02 getSingle() {
if (s == null) {
s = new Single02();
}
return s;
}
}
懒汉式的安全问题
一个线程判断完变量s=null,还没有执行new对象是cpu被另外一个线程抢到进行判断并且new对象,因此对象被创建的多次
解决办法
加锁控制线程
//方法get返回本类对象
public static Single02 getSingle() {
synchronized (Single02.class) {
if (s == null) {
s = new Single02();
}
}
return s;
}
提高效率:第一个线程获取锁,创建对象,返回对象,第二个线程调用方法的时候,变量s已经有对象了,就不需要在进行同步了,不要再判断空,直接return才高效(DCL)
//方法get返回本类对象
public static Single02 getSingle() {
if (s == null) {
synchronized (Single02.class) {
if (s == null) {
s = new Single02();
}
}
}
return s;
}
3、关键字volatile
成员变量修饰符,不能修饰其他内容
关键字的作用:
保证被修饰的变量,在线程中的可见性
防止指令重排序单例的模式,使用了关键字,不使用关键字可能会使线程拿到一个尚未初始化完成的对象(半初始化对象)
六、线程池ThreadPool
线程的缓冲池,目的就是提高效率,new Thread() .start(),线程是内存中的一个独立的方法栈区,JVM没有能力开辟内存空间,和OS交互
JDK开始内置线程池
1、Executors类
静态方法:static newFixedThreadPool(int 线程的个数)
方法的返回值ExecutorService接口的实现类,管理池子里的线程
ExecutorService接口的方法
submit(Runnable r)提交线程执行的任务
2、Callable接口
实现多线程的程序:接口的特点是有返回值,可以抛出异常(Runnable没有)
抽象方法只有一个:call
启动线程,线程调用重写方法call
ExecutorService接口的方法
submit(Callable c)提交线程执行的任务
Future submit()方法提交线程任务后,方法有个返回值Future接口类型
Future接口,获取到线程执行后的返回值结果
七、ConcurrentHashMap
ConcurrentHashMap类本质上时Map集合,键值对的集合,使用方式和HashMap没有区别
凡是对此Map集合的操作,不去修改里面的元素,不会锁定
八、线程的生命状态图-生命周期
在某一时刻,线程只能处于其中的一种状态,这种线程的状态反应是JVM中的线程状态和OS无关
九、File类
1、文件夹 Directory : 存储文件的容器,防止文件重名而设置,文件归类,文件夹本身不存储任何数据, 计算专业数据称为 目录
2、文件 File : 存储数据的,同一个目录中的文件名不能相同
3、路径 Path : 一个目录或者文件在磁盘中的位置
4、File类,描述目录文件和路径的对象
5、平台无关性
1、 File类的构造方法
- File (String pathname)传递字符串的路径名
- File(String parent,String child)传递字符串的父路径,字符串的子路径
- File(File parent,String child)传递File类型的父路径,字符串的子路径
2、 File类的创建方法
- boolean createNewFile()创建一个文件,文件路径写在File的构造方法中
- boolean mkdirs()创建目录,目录的位置和名字写在File的构造方法中
3、 File类的删除方法
- boolean delete() 删除指定的目录或者文件,路径写在File类的构造方法
注:不会进入回收站,直接从磁盘中删除了,有风险
4、 File类判断方法
- boolean exists() 判断构造方法中的路径是否存在
- boolean isDirectory()判断构造方法中的路径是不是文件夹
- boolean isFile()判断构造方法中的路径是不是文件
- boolean isAbsolute() 判断构造方法中的路径是不是绝对路径
绝对路径:
- 在磁盘中的路径具有唯一性
- Windows系统中,盘符开头
- Linux或者Unix系统, /开头,磁盘根
- 互联网路径 :
www.baidu.com
相对路径:
- 必须有参照物
例C:/Java/haha/bin/javac.exe
- bin是参考点 : 父路径 C:/Java/haha
- bin是参考点 : 子路径 javac.exe
- bin参考点: 父路径使用 …/表示