2.线程和进程
- wait/sleep的区别
- 来自不同的类
wait=>Object
sleep=>Thread - 关于锁的释放
wait会释放锁,sleep会抱着锁睡觉 - 使用的范围不同
wait必须在同步代码块中,sleep任何地方 - 是否需要捕获异常
wait不需要,sleep必须捕获
- 线程六大状态
3.lock锁
public class SaleTicketLock {
public static void main(String[] args) {
//创建资源类对象
Ticket ticket = new Ticket();
//创建线程
new Thread(() ->{
for (int i = 0; i < 40; i++) ticket.sale();},"A").start();
new Thread(() ->{ for (int i = 0; i < 40; i++) ticket.sale(); },"B").start();
new Thread(() ->{ for (int i = 0; i < 40; i++) ticket.sale(); },"C").start();
}
}
//资源类
class Tickets{
private int number = 50;
//创建锁对象
Lock lock = new ReentrantLock();
//卖票的方式
public void sale(){
//加锁
lock.lock();
try {
if (number >0){
System.out.println(Thread.currentThread().getName()+"卖出了第"+(number--)+"张票剩余"+number);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//释放锁
lock.unlock();
}
}
}
synchronized和lock区别:
- synchronize内置的java关键字,lock是一个java类
- synchronize无法获取锁的状态,lock可以判断是否获取到了锁
- 前者会自动释放锁,lock必须手动释放锁,如果不释放锁,会造成死锁
- 前者线程1(获得锁,阻塞)线程2(等待,一直等);lock就不一定会等待下去。lock.tryLock();
- 前者可重入锁,不可以中断,非公平;lock,可重入锁,可以判断锁,非公平(可以自己设置);
- 前者锁少量的代码同步问题,lock适合锁大量的同步代码!
锁是什么?如何判断锁的是谁?
new this 具体的一个手机
static Class 唯一的一个模板
4.生产者,消费者问题
6、集合类不安全
package com.it;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
// java.util.ConcurrentModificationException
public class Test {
public static void main(String[] args) {
//并发下ArrayList不安全
/*
* 解决方案:
* 1.List<String> list = new Vector<>();
* 2. List<String> list = Collections.synchronizedList(new ArrayList<>());
* 3.List<String> list = new CopyOnWriteArrayList<>();
* CopyOnWrite写入时复制, COW 计算机程序设计领域的一种优化策略;
* 多个线程调用的时候,list,读取的时候固定的,写入时(覆盖)
* 在写入的时候避免覆盖,造成数据问题*/
List<String> list = new CopyOnWriteArrayList<>();
//List<String> list = new Vector<>();
for (int i = 0; i < 10; i++) {
new Thread(()->{
list.add(UUID.randomUUID().toString().substring(0,5));
System.out.println(list);
},String.valueOf(i)).start();
}
}
}
7、Callable
与Runbale区别:
-
可以有返回值
-
可以抛出异常
-
方法不同,run()/call()
package com.it.test;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;public class CallableTest {
public static void main(String[] args) throws ExecutionException, InterruptedException {
MyThread myThread = new MyThread();
//适配类
FutureTask futureTask = new FutureTask<>(myThread);
new Thread(futureTask,“A”).start();
new Thread(futureTask,“B”).start();//结果会被缓存
Integer o = (Integer) futureTask.get();//这个get可能会产生阻塞
System.out.println("o = " + o);}
}
class MyThread implements Callable{@Override public Integer call() throws Exception { System.out.println("call()");//会打印几个call //耗时的操作 return 1024; }
}