多线程JUC

案例
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 〈一句话功能简述〉
* 〈〉 * * @author dhy * @create 2020/5/24 * @since 1.0.0 */
public class SaleTicketDemo { public static void main(String[] args) throws InterruptedException{ Ticket ticket = new Ticket(); ExecutorService executorService = Executors.newFixedThreadPool(50); for (int j = 0; j < 50; j++) { executorService.execute(()->{ for (int i = 0; i < 20; i++) { ticket.sale(); } }); } Thread.sleep(2000); System.out.println(ticket.number); System.out.println(CountTest.count);//结果大于500,出现了安全问题; executorService.shutdown(); } } class Ticket { public int number = 10; public void sale(){ //增加线程出现安全问题概率,停留线程在这里,一起等待cpu执行 try { Thread.sleep(100); } catch (Exception e){ e.printStackTrace(); } if(number > 0){ System.out.println(Thread.currentThread().getName() + "剩余:" + number--); synchronized (CountTest.class){ CountTest.count++; } } } } class CountTest{ public volatile static int count = 0; }
当线程数量大于500进入if(number > 0),说明线程操作数据大于500次,不符合预期值,存在多线程安全问题。
Synchronized 和 Lock 区别
1. synchronized 内置java关键字;Lock 是一个java类;
2. synchronized 无法判断获取锁的状态;Lock 可以判断是否获取到了锁;
3. synchronized 会自动释放锁;Lock 必须手动释放锁,如果不释放,死锁;
4. synchronized 线程会一直等待锁;Lock 不一定等待下去;
5. synchronized 可重入锁,不可以中断,非公平;Lock 可重入锁,可以判断锁,非公平或者公平;
6. synchronized 适合少量代码同步问题;Lock 适合大量同步代码;
Lock实现类
ReentrantLock(可重入锁), ReentrantReadWriteLock.ReadLock(读锁), ReentrantReadWriteLock.WriteLock(写锁)
ReentrantLock
public ReentrantLock() {
        sync = new NonfairSync();//非公平锁
    }

 public ReentrantLock(boolean fair) {
        sync = fair ? new FairSync() : new NonfairSync();//true 公平锁,false 非公平锁
    }

- 公平锁:先来后到;
- 非公平锁:可以插队;
虛假唤醒
不能用if判断,要用while判断;可以查看jdk文档;
生产者和消费者
Lock lock = new ReentrantLock();
lock.lock();
lock.unlock();
Condition condition = lock.newCondition();
condition.await();//等待
condition.signalAll();//唤醒
**如果需要按顺序执行,可以创建多个Condition**
异常
java.util.ConcurrentModificationException//并发修改异常
集合
ArraryLsit 线程不安全;
    - List<String> list = new ArrayList<>();//不安全
    - List<String> list = new Vector<>();//安全
    - List<String> list = Collections.synchronizedList(new ArrayList<>());//安全
    - List<String> list = new CopyOnWriteArrayList<>();//**最佳安全方式**
HashSet 线程不安全;
    - 同ArraryLsit
HashMap 线程不安全;
    -Map<String,String> map = Collections.synchronizedMap(new HashMap<>());//安全
    -Map<String,String> map = new ConcurrentHashMap();//安全
CopyOnWriteArrayList:写入时复制-COW,计算程序设计领域的一种优化策略;
CopyOnWriteArrayList底层用的ReentrantLock,Vector底层用的synchronized;
ArrayList底层扩展原理:Arrays.copyOf(elementData, newCapacity);
HashSet底层原理就是return map.put(e, PRESENT)==null;
接口Callable
java.util.concurrent.FutureTask
类型参数:
V - 此 FutureTask 的 get 方法所返回的结果类型。
已实现的接口: **Runnable** 
FutureTask(Callable callable) 
          创建一个 FutureTask,一旦运行就执行给定的 Callable。
特点:
	- 可以返回结果,但是有可能造成阻塞;
	- 可以抛出异常;
	- 结果可被缓存;

你可能感兴趣的:(juc,并发编程,多线程)