java基础语法-线程

一、线程的概念

a)什么是进程
在操作系统下并发的多个任务。
并发的原理:宏观并行,微观串行。
解释:cpu在同一个时间段只能运行一个应用程序,OS(操作系统)会为每一个软件分配一定的时间片,多个应用在不同的时间片交替执行。由于cpu运行的速度是非常快的,导致宏观上应用程序是并行,其实微观上是串行。

b)什么是线程
相当于轻量级的进行。在一个进程中可以同时运行多个任务。线程是进程的执行单位。
线程的组成部分:
i.CPU:由os分配时间片
ii.数据:
1.堆空间:对象 堆空间共享(成员变量)
2.栈空间:局部变量 栈空间独有
iii.多线程代码

二、创建线程的方式

a) 第一种方式
i.写一个任务类 继承 一个Thread类
class A extends Thread{}
ii.覆盖run() 需要执行的任务
iii.创建线程对象
iv.启动线程
通过start()启动新创建的线程,由JVM自动调用run()方法去执行任务。

b)第二种方式
i.实现Runnable接口。
ii.覆盖run();
iii.创建任务对象,并将其作为参数传给Thread。
iv.启动线程。

三、线程的状态
在这里插入图片描述

a)常见方法
i.static void sleep(long millis);//在指定的时间毫秒内进入有限期等待。
ii.void join();//加入到其他线程中 优先执行,当自身线程执行完毕,其他线程才会执行。
iii.static void yield();//暂停当前的线程对象,并执行其他线程。有可能操作系统还是会选中它。
iv.t1.setPriority(10);//设置线程对象的优先级
v.void setDaemon(boolean b);将此线程设置为精灵线程,守护线程。
当其他线程执行完毕而守护线程仍然没有执行完毕时,也将停止执行。
守护线程:垃圾回收线程

在这里插入图片描述

四、线程同步

a)同步: 形容一次方法的调用,一旦同步开始,那么调用者会等待方法的返回,才能继续执行。 只有一条执行路径。
异步:形容一次方法的调用,一旦异步开始,就相当于一次信息的传递,信息传递结束立刻返回,竞争时间片,并行执行。,有多条执行路径

b)线程不安全
当多线程并发访问临界资源时,如果破坏了原子性,则会导致数据结果不一致。
临界资源:同一个对象 堆空间共享的对象
原子性: 不可分割的多步操作,将其看成一个整体 ,执行的顺序不可颠倒,内容不可缺省。

c)在java中,每一个对象都有一个互斥锁标记,可以分配给线程。
synchronized

i.同步代码块
synchronized(o){
//代码块 原子操作
}
当线程拿到对象的互斥锁标记,才可以执行该对象的内部的代码块。
当代码块执行完毕后,释放锁标记。拿不到锁标记就会进入到堵塞状态。

ii.同步方法
synchronized可以修饰方法
语法: 访问修饰符 synchronized 返回值类型 方法名(){
//原子操作
}
//相当于
synchronized(this){
}

d) 线程安全的类:StringBuffer、Vector、Hashtable
类中的方法普遍都为synchronized修饰的
线程不安全的类:StringBuilder、ArrayList、HashMap
类中的方法都不是 synchronized修饰的。

五、线程通信
wait(); 必须在对临界资源加锁的同步代码块中。一旦一个线程调用了wait(),就会释放掉所有的锁标记,进入等待队列。

notify()/notifyAll():必须在对临界资源加锁的同步代码块中。一旦一个线程调用了notify()/notifyAll,那么就会唤醒在等待中的一个或者所有线程。线程一旦唤醒之后,如果获得时间片,并且拿到锁标记就会进入运行状态

六、sleep()和wait()区别
sleep();//有限期等待 不会释放锁标记
wait();//一旦线程调用了wait(),就会进入到等待序列,同时释放所有的锁标记

七、线程池
a)概念
线程池:线程容器,可设定线程分配的数量上限,将预先创建线程对象存入池中,并重用线程池中的线程。

b)常用的接口和类
i.Executor :线程的顶级的接口
ii.ExecutorService 线程池接口,Executor的子接口
iii.Executors:工具类,所有的方法都是静态方法。通过此类可以获得一个线程池。
1.通过 newFixedThreadPool(int nThreads) 获取固定数量的线程池。参数:指定线程池中线程的数量
详见代码TestThread4.java
2. 通过newCachedThreadPool() 获得动态数量的线程池如不够则创建新的,没有上限。
详见代码TestThread4.java

八、Callable接口
a)JDK1.5的类 与Runnable类似,实现之后都是代表一个线程任务
Runnable :不能抛异常;没有返回值。
b)方法
V call(); //好处:抛出一个Exception异常;存在返回值。
好处:减少创建和销毁线程的次数,每个工作线程可用于执行多个任务,只需将任务提交给线程,即可重复利用。

九、Future接口
a)概念:异步计算的结果,ExecutorService.submit()所返回的状态结果,当中包含了call()的返回值。
b)方法:V get()
//获得Future对象中call()的执行结果(根据Callable的泛型决定V的具体类型)

在这里插入图片描述

十、Queue JDK1.5Collection集合的接口

模拟队列 先进先出
a)常用方法
i.boolean add(obj);//将元素顺序插入到集合中,当达到容量上限时,不自动扩容。而且会抛异常。
ii.boolean offer(obj);//将元素顺序添加一个元素。当容量达到上限时,不会抛异常,会返回一个false。
iii.Object remove(obj);//将指定元素移除。如果集合中没有元素了,会抛出异常。返回的被移除的元素
iv.Object pool(obj);//将指定元素移除。返回被移除的元素。

十一、Lock
所在包java.util.concurrent.locks;替换早期的synchronized、锁的分级

a)常用方法
i.void lock();//获得锁 如锁被占用,则等待。
ii.void unlock();//释放锁
iii.boolean tryLock();//尝试获取锁 获取不到返回false 不会等待。

b)实现类
ReentrantLock:与synchronized相比逻辑控制更灵活、直观,但必须手动释放锁。

c)读写锁
ReadWriteLock,所在包java.util.concurrent.locks
概念:一种支持一写多读的同步锁,可分别分配读锁、写锁。
方法:ReadWriteLock wrl = new ReentrantReadWriteLock();
//可重入的读写锁
Lock read = wrl.readLock(); // 获取读锁
Lock write = wrl.writeLock(); // 获取写锁
使用场景:当读操作远远高于写操作时,可以使用读写锁提高性能。

d)List的线程安全的实现类
CopyOnWriteArrayList:所在包java.util.concurrent;读操作远远大于写操作时,效率高。 读不加锁,牺牲写的效率去换取读操作的效率。利用复制数组的方式实现数组元素的修改.
e)ConcurrentHashMap:内部细分若干个小的HashMap,称为段(16段)
f). ConcurrentLinkedQueue :所在包java.util.concurrent;是Queue接口的常用实现类,基于链表实现的队列,采用比较交换算法,简称CAS无锁算法,特点是无锁并且线程安全的类。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值