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参考点: 父路径使用 …/表示
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值