JAVA多线程Thread

jdk1.8中文api文档下载

Lock

实现类
ReentrantLock();

构造方法
NonfairSync();非公平锁
FairSync();公平锁 可以先来后到
在这里插入图片描述

lock和synchronized的区别

synchronizedlock
java关键字java类
无法判断锁的状态可以判断是否获取到了锁
会自动释放锁lock锁需要手动释放(不释放会死锁)
线程获取到不到锁会一直等待lock.tryLock() 可以尝试获取锁,可设置超时时间
可重入锁,不可中断,非公平可重入锁,可以设置是否公平锁
适合锁少量代码同步问题适合锁大量同步代码块

synchronized和lock锁实现卖票问题

package com.yunwangl.juc.ticket;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Stream;

/**
 * @ClassName SellTicket
 * @Description
 * @Author LiuQunYu
 * @Date 2021/3/22 21:06
 * @Version V1.0
 **/
public class SellTicket {

    public static void main(String[] args) {

//        synchronizedSell(); // synchronized关键词实现
        LockSell(); // lock锁实现
    }


    public static void LockSell() {
        TicketLock ticket = new TicketLock();
        Stream.of("线程1", "线程2", "线程3", "线程4", "线程5").forEach(name -> {
            new Thread(() -> {
                while (ticket.num > 0) {
                    ticket.sell();
                }
            }, name).start();
        });
    }

    static class TicketLock {
        private Lock lock = new ReentrantLock();
        private int num = 1000;

        public void sell() {
            lock.lock();
            try {
                if (num > 0) {
                    System.out.println(Thread.currentThread().getName() + "卖出了第" + this.num-- + "张票");
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }

    }


    public static void synchronizedSell() {
        Ticket ticket = new Ticket();
        Stream.of("线程1", "线程2", "线程3", "线程4", "线程5").forEach(name -> {
            new Thread(() -> {
                while (ticket.num > 0) {
                    ticket.sell();
                }
            }, name).start();
        });
    }

    static class Ticket {
        private int num = 1000;

        public synchronized void sell() {
            if (num > 0) {
                System.out.println(Thread.currentThread().getName() + "卖出了第" + this.num-- + "张票");
            }
        }

    }
}


消费者生产者问题

线程等待避免使用if 应使用while循环判断
在这里插入图片描述

在这里插入图片描述
synchronized 线程等待
this.wait();
唤醒线程
this.notifyAll();

lock锁实现

final Condition condition = lock.newCondition();
condition.await();
condition.signalAll();
package com.yunwangl.juc.consumer;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Stream;

/**
 * @ClassName Demo
 * @Description
 * @Author LiuQunYu
 * @Date 2021/3/23 0:15
 * @Version V1.0
 **/
public class Demo {


    public static void main(String[] args) {
//        synchronizedDataPC();
//        lockDataPC();
        OrderPrintMethod();
    }

    /**
     * synchronized 实现消费者生产者问题
     */
    public static void synchronizedDataPC() {
        Data data = new Data();
        Stream.of("生产者线程1", "生产者线程2", "生产者线程3").forEach(name -> {
            new Thread(() -> {
                while (true) {
                    try {
                        data.increment();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }, name).start();
        });

        Stream.of("消费者线程1", "消费者线程2", "消费者线程3").forEach(name -> {
            new Thread(() -> {
                while (true) {
                    try {
                        data.decrement();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }, name).start();
        });
    }

    /**
     * synchronized 具体业务类
     */
    static class Data {
        private int num = 0;

        public synchronized void increment() throws InterruptedException {
            while (num != 0) {
                // 等待消费
                this.wait();
            }
            num++;
            System.out.println(Thread.currentThread().getName() + "生产数据->" + num);
            // 生产数据完成 通知消费者消费
            this.notifyAll();
        }

        public synchronized void decrement() throws InterruptedException {
            while (num == 0) {
                // 等待生产者生产
                this.wait();
            }
            // 消费数据
            num--;
            System.out.println(Thread.currentThread().getName() + "消费数据->" + num);
            // 通知生产者生产数据
            this.notifyAll();
        }
    }


    /**
     * lock锁实现简单消费者生产者问题
     */
    public static void lockDataPC() {
        LockData data = new LockData();
        Stream.of("生产者线程1", "生产者线程2", "生产者线程3").forEach(name -> {
            new Thread(() -> {
                while (true) {
                    data.increment();
                }
            }, name).start();
        });

        Stream.of("消费者线程1", "消费者线程2", "消费者线程3").forEach(name -> {
            new Thread(() -> {
                while (true) {
                    data.decrement();
                }
            }, name).start();
        });
    }


    /**
     * lock锁具体业务类
     */
    static class LockData {
        Lock lock = new ReentrantLock();
        final Condition condition = lock.newCondition();
        private int num = 0;

        public void increment() {
            lock.lock();
            try {
                while (num != 0) {
                    // 等待消费
                    condition.await();
                }
                // 生产数据
                num++;
                System.out.println(Thread.currentThread().getName() + "生产数据->" + num);
                // 生产数据完成 通知消费者消费
                condition.signalAll();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }

        public void decrement() {
            lock.lock();
            try {
                while (num == 0) {
                    // 等待生产者生产
                    condition.await();
                }
                // 消费数据
                num--;
                System.out.println(Thread.currentThread().getName() + "消费数据->" + num);
                // 通知生产者生产数据
                condition.signalAll();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }

        }
    }


    static void OrderPrintMethod() {
        OrderPrintData orderPrintData = new OrderPrintData();

        new Thread(() -> {
            while (true) {
                orderPrintData.print1();
            }
        }, "线程1").start();

        new Thread(() -> {
            while (true) {
                orderPrintData.print2();
            }
        }, "线程2").start();
        new Thread(() -> {
            while (true) {
                orderPrintData.print3();
            }
        }, "线程3").start();
    }


    /**
     * lock锁实现线程顺序打印依次执行
     */
    static class OrderPrintData {
        Lock lock = new ReentrantLock();
        final Condition condition1 = lock.newCondition();
        final Condition condition2 = lock.newCondition();
        final Condition condition3 = lock.newCondition();
        private int num = 1;

        public void print1() {
            lock.lock();
            try {
                while (num != 1) {
                    // 等待
                    condition1.await();
                }
                System.out.println(Thread.currentThread().getName() + "打印->" + num);
                num = 2;
                // 通知其他线程
                condition2.signal();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }

        public void print2() {
            lock.lock();
            try {
                while (num != 2) {
                    // 等待
                    condition2.await();
                }
                System.out.println(Thread.currentThread().getName() + "打印->" + num);
                num = 3;
                // 通知其他线程
                condition3.signal();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }

        public void print3() {
            lock.lock();
            try {
                while (num != 3) {
                    // 等待消费
                    condition3.await();
                }
                System.out.println(Thread.currentThread().getName() + "打印->" + num);
                num = 1;
                // 通知其他线程
                condition1.signal();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    }
}

锁问题 synchronized
没有被synchronized修饰的方法不受锁的影响

修饰类型锁的目标
修饰普通方法锁对象
修饰static方法锁类
修饰普通成员变量锁对象
修饰static成员变量锁类

集合并发修改问题

类名方法
ArrayList在这里插入图片描述
Vector在这里插入图片描述
Collections.synchronizedList()在这里插入图片描述
CopyOnWriteArrayList在这里插入图片描述
package com.yunwangl.juc.list;

import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * @ClassName Demo
 * @Description 多线程并发集合修改问题
 * @Author LiuQunYu
 * @Date 2021/3/26 0:04
 * @Version V1.0
 **/
public class Demo {

    public static void main(String[] args) {
//        concurrenceList();
//        concurrenceVector();
//        concurrenceSyList();
        concurrenceCopyOnWriteList();
    }

    /**
     * list 并发操作测试
     *
     * 发生ConcurrentModificationException 并发修改异常
     */
    static void concurrenceList() {
        List<String> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                list.add(String.valueOf(UUID.randomUUID()));
                System.out.println(list);
            }).start();
        }

    }

    /**
     * 使用Vector集合解决并发修改异常问题 底层使用synchronized
     */
    static void concurrenceVector(){
        List<String> list = new Vector<>();
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                list.add(String.valueOf(UUID.randomUUID()));
                System.out.println(list);
            }).start();
        }
    }

    /**
     * 使用集合工具Collections.synchronizedList 底层为内部类new SynchronizedList<>(list));
     * <p>
     *     public boolean add(E e) {
     *             synchronized (mutex) {return c.add(e);}
     *         }
     * </p>
     */
    static void concurrenceSyList(){
        List<String> list = Collections.synchronizedList(new ArrayList<String>());
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                list.add(String.valueOf(UUID.randomUUID()));
                System.out.println(list);
            }).start();
        }
    }

    /**
     * 底层实现 private transient volatile Object[] array;
     */
    static void concurrenceCopyOnWriteList(){
        List<String> list = new CopyOnWriteArrayList<String>();
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                list.add(String.valueOf(UUID.randomUUID()));
                System.out.println(list);
            }).start();
        }
    }
}

线程池

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler)

volatile关键词

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值