多线程:
1.掌握 一个线程处理一个任务,不需要 同步锁 ,----> 迅雷 一对一
2.多个线程 共享一个资源, 必须使用同步锁 ,要保证数据的安全性 多对一
3.多个线程 共享多个资源, 哲学家就餐 (死锁) 多 对 多
4.线程之间的通讯 在某种场景下 , 只有相互 唤醒对象 线程才能保证程序的正常执行
Thread类的重要方法:
1.sleep();
2.join();
3.yield();
4.currentThread();
5.getName();
6.run();
7.start();
8.isDeamon();
setDeamon();
Object:
notify(); 在线程的等待池中 随机 唤醒一个
notifyAll(); 将线程池中所有等待的线程 都唤醒
wait();
-------------------------------------------------------
JUC: java.util.concurrent. 1.5 ---> java 提供的 并发包
ArrayBlckingQueue:
特点 FIFO : put(); take();
1.java提供了 3中实现 多线程的方式:
1)继承Thread类
2)实现Runnable接口
3)实现Callable接口
1.Callable接口 是 类似于 Runnable接口的 ,都是实现多线程的方式
但是Callbable 重写的是 call方法 有返回值, 声明异常
run方法没有返回值 , 不声明异常
在使用Callbable接口启动线程时 ,必须使用FutureTask辅助类
来完成启动功能,我们也可以调用FutrueTask辅助类的
get() 获取方法的范沪指, 使用cancel方法 取消摸个线程的执行;
FutureTask:
new FutrueTask(Callable callbale);
get(); 获取返回值
cancel();取消
------------------------------------------------------------
java中 同步锁:
1.synchronized 关键字
同步代码块儿
synchronized(this){
}
同步方法
public synchronized void haha(){
}
2. Lock 接口
lock(); 上锁
unlock(); 释放锁
lock.tryLock(); 只有在调用时才可以获得锁
lock 锁 和 synchronized
1.lock()是方法
synchronized 是关键字
2.lock锁必须 手动释放
synchronized 自动释放锁 ,jvm虚拟机 的释放
------------------------------------------
并发包下的集合:
ConcurrentHashMap: 锁分段机制
Hashtable
Vector
ArrayList: 线程不安全, 多个线程在向ArrayList添加元素时
会出现null值,数据丢失问题
Vector可以解决这个问题,因为他是线程安全的,但是不支持 复合操作(一边输出,一边添加)
List list = Collections.synchronizedList(new Array());
这个方式可以将一个线程不安全的 类转换为 线程安全的类, 但是不支持 复合操作
以上三个都不是最好的, 所以在java.util.concrrent.CopyOnWriteArrayList
及是线程安全的, 有支持 复合操作
Collections:
高级部分:
Lock
Callable
ConcurrentHashMap 和 Hashtable 的区别:
CopyOnWriteArrayList: 保证复合操作, 线程安全
复制并写入 添加, 删除 -- 》 性能 慢 , 查询快
------------------------------------------------------
1.闭锁:
1. CountDownLatch(int count); 里面维护了一个变量
这个变量的个数 必须是 线程的个数
2.await(); 让当前正在执行的线程进入阻塞状态
3.countDown(); 每次执行这个方式时 会将count 变量-1
知道为 0 时, 会释放 正在等待的线程
2.线程八锁:
线程八锁: 只的是 使用同步锁的 八种情况;
1.两个线程 调用了 普通同步方法, 直接输出 One Two
两个线程用的是 一把锁
2.两个线程 调用了 普通的同步方法, 在One中休眠了3s, 结果 等待 3s后 一起输出 One Two
3.三个 方法 ,有两个同步方法,一个非同步方法,
两个同步方法持有的是 一个把锁, 非同步方法没有锁,
4.两个普通的 同步方法, 但是创建了两次对象
在调用 One , Two时 输出的是 ,Two 3s One 那说明是两把锁
5. 一个是静态 同步方法, 一个是 普通同步方式
一个对象 ,调用 One ,Two 结果是 Two 3s One 两把锁 ,
一个是 number对象锁, 另一个是 Number.xxx类型的锁
6. 两个 静态 同步方法 ,调用One Two , 结果为: 3s One Two 说明是一把锁
7. 两个静态 同步方法, 两个对象 ,调用One Two ,
结果为: 3s, One Two 说明 一把锁
8. 一个静态同步方法, 一个普通同步方法,
两个Number对象, 调用One, Two ,
Two , 3s , One 两把锁
重点 :
new 一次就是 一个锁 :
所有static 修饰的内容都是一把锁 Class
3.线程池
我们在使用线程是 ,我们会频繁的创建 和 销毁线程
是很耗时 和 消耗 性能的; java为了 优化线程的创建和 销毁
体用了一个 叫线程池的 工具
Executors.newCachedThreadPool(); 无限 线程数
Executors.newFixedThreadPool(int a); 指定线程池中有几个线程
Executors.newSingleThreadExecutor();次线程池中 就一个线程
线程池 中维护了 一个 线程队列:
原理 FIFO ,先进先出 ,一定是从第一个位置拿线程
输出结果,不能保证
ExecutorService接口:
常用方法: 给线程池中的线程分配任务
submit(Callable callable);
submit(Ruuable runnable);
shutDown(); 关闭线程池