3.多线程之JUC并发编程0

这篇具有很好参考价值的文章主要介绍了3.多线程之JUC并发编程0。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.学习方法 java1.8才有juc 面试高频问

源码+官方文档
//怎么用多线程,如果是没有返回结果的就单独开一条线程,或者使用线程池,如果有返回值的就用callable

   // 获取当前帧中出现的人脸对应的特征码
             utureTask<String> stringFutureTask = new FutureTask<String>(()->{
                        String s = FaceEngineService.detectFace(faceFeature);
                        return s;
                    });

2.什么是juc 三个包

java.util.concurrent
java.util.concurrent.atomic
java.util.concurrent.locks

  1. 介绍
  1. Callable性能比Runnable高,并且Runnable没有返回值
  2. 进程和线程
    进程: 一个程序比如QQ.exe
    线程 在QQ里面同时打字和聊天 分别是一个线程
  3. java可以开线程吗?
    不可以 java只能调native方法使用c++调用
  4. 并发和并行
    并发:多线程操作同一资源 cpu 1个核快速交替运行模拟出多线程
    并行: 多个人一起行走 cpu多核多个线程可以同时执行

4.线程有几个状态 6个…代码有但是java课说5个

NEW
RUNNABLE
BLOCK
WAITING
TIMED_WAITING
TERMINATED

4.wait和sleep的区别

  1. 来自不同类
    wait(Object) sleep(Thread)
  2. 锁的释放
    wait释放 sleep抱着锁睡觉
  3. 使用范围不同
    wait必须在同步代码块中使用
    sleep任何地方使用
  4. 是否捕获异常
    wait不需要 (同步代码块中)
    sleep需要 ,会发生超时等待的情况 oop编程面向对象编程

5.Lock锁接口

  1. 实现类
    ReentrantLock true为公平锁 false默认为非公平锁
    ReentrantReadWriteLock.ReadLock读锁
    ReentrantReadWriteLock.WriteLock写锁
  2. 公平锁和非公平锁
    公平:可以先来后到(公平的) 如果3小时的任务后面是3s的任务 非常不公平,公平是相对的…在社会中也是一样…
    非公平(默认):不公平 可以插队

6.Lock三部曲 等待 业务 通知

1.创建资源类(有成员变量和锁)
2.里面加锁 lock 和 unlock
3.main方法创建多个线程.start();操作资源类

7.synchronized和lock的区别

  1. sychronized是java关键字,Lock是java类
  2. sychronized 无法判断锁状态 lock可以判断锁
  3. sychronized自动释放锁 ,lock需要手动释放不让死锁
  4. sychronized线程1得到锁阻塞,线程二傻傻等待释放,lock不一定会等待下去
  5. sychronized可重入锁不可中断,sychronized是否公平锁(由cpu自己决定) ;lock可重入锁,可以判断锁状态非公平(自己设置)
  6. sychronized适合锁少量代码同步问题;Lock锁大量同步代码

8.传统生产者和消费者问题的问题(虚假唤醒问题) 同时开启2个消费者和2个生产者 发现还是不安全
//之前我的困惑是启动了多个消费者和提供者还是会产生超前消费的问题
//,解决把if判断改成while判断资源

while(number!=0){}; //因为if只判断一次,其他线程会唤醒这个线程,所以导致虚假唤醒

public class LightWay {
    public static void main(String[] args) {
        Container1 container1 = new Container1();
        new Producer1(container1).start();
        new Producer1(container1).start();
        new Customer1(container1).start();
        new Customer1(container1).start();

    }
}

class Producer1 extends Thread{
    Container1 container1;
    Producer1(Container1 container1){
        this.container1=container1;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {

            container1.set(i+"");

        }
    }
}
class Customer1 extends Thread{
    Container1 container1;
    Customer1(Container1 container1){
        this.container1=container1;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {

            try {
                container1.get();

            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
class Container1{
    boolean flag=true;
    String thing="";
    public synchronized void set(String thing)  {
        while(!flag){   //改为if为while,不停判断,而不是判断一次
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("生产了"+thing);
        this.thing=thing;
        this.flag=!flag;
        this.notifyAll();

    }
    public synchronized void get() throws InterruptedException {
        while (flag){
            this.wait();
        }
        System.out.println("消费了"+thing);
        this.flag=!flag;
        this.notifyAll();

    }

}

9.JUC的问题: synchronized有wait和notify线程通信,Lock有Condition的await和signal,Lock也用while循环判断

//任何新技术,不是前面技术的覆盖,一定有其优势,我想要 a线程执行完通知b,b执行完通知c
//可以精准通知,如下执行结果为 BCA这样的顺序 可以是BABABA 或者CACACABA执行

public class ConsumerAndProducerJUC1 {
    public static void main(String[] args) {
        TikectAction tikect = new TikectAction();
        new Thread(()->{
            for (int i = 0; i < 100; i++) {
                tikect.buy();
            }

        },"A").start();
        new Thread(()->{
            for (int i = 0; i < 100; i++) {
                tikect.give();
            }

        },"B").start();
        new Thread(()->{
            for (int i = 0; i < 100; i++) {
                tikect.give();
            }

        },"C").start();

    }

}


//资源类 ,包括他的操作要加锁
class TikectAction{
    int num=0;
    ReentrantLock lock=new ReentrantLock();
    Condition condition1= lock.newCondition();
    Condition condition2= lock.newCondition();
    int conditionNum=1;

     void  give(){
        lock.lock();
        try{
            //业务代码
            while (num>0){
                if(conditionNum!=1){
                    condition1.await(); //等待
                }

            }

            num++;
            conditionNum=2;
            System.out.println(Thread.currentThread().getName()+"生产第"+num+"张票");
            condition2.signal(); //通知线程2
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }



    }
    void buy(){
        lock.lock();
        try{
            //业务代码
            while (num<=0){
                if(conditionNum!=2){
                    condition2.await();
                }
            }
            System.out.println(Thread.currentThread().getName()+"消费第"+num+"张票");
            num--;
            conditionNum=1;
            condition1.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }

    }


}

10.八锁问题(本质还是探讨线程和线程,锁与锁 还有加上static或者多个对象和单个对象之间的关系)
!!!run方法是按启动顺序执行的

  1. 标准情况下两个线程的锁方法(不用继承Thread类) 没有锁对象,加了sleep方法的线程后执行
public class eightLockProblems {

    public static void main(String[] args) throws InterruptedException {
        A1 a1 = new A1();
        new Thread(()->{//反正就是sleep后执行,可以运行的先执行
            try {
                a1.sendSMS();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"send").start();

        new Thread(()->{a1.call();},"call").start();
    }


}
class A1 {

    public  void call(){

        System.out.println("打电话");
    }
    public  void sendSMS() throws InterruptedException {
        TimeUnit.SECONDS.sleep(10);
        System.out.println("发短信");
    }

}
//,先打电话然后 发短信
  1. synchronize的方法 new2个线程.线程1 : TimeUnit.SECONDS.sleep(1) 线程2: 不写sleep,用的同一个锁对象,一定先执行线程1的
    ,不是执行顺序决定的,而是方法的锁的是对象,谁先拿到谁先执行
public class eightLockProblems {

    public static void main(String[] args) throws InterruptedException {
        A1 a1 = new A1();
        new Thread(()->{//无论执行多少次都是发短信打电话这个顺序,因为他先拿到a1这个锁对象
            try {
                a1.sendSMS();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"send").start();

        new Thread(()->{a1.call();},"call").start();
    }


}
class A1 {

    public synchronized void call(){

        System.out.println("打电话");
    }
    public synchronized void sendSMS() throws InterruptedException {
        TimeUnit.SECONDS.sleep(10);
        System.out.println("发短信");
    }

}

3.资源类加个普通方法在线程内调用,执行顺序 先执行普通方法(因为没有资源竞争,不存在锁的问题,锁是要等待的,普通方法不用,所以一直是第一位显示)


public class eightLockProblems {
      //输出  普通方法  发短信 打电话
    public static void main(String[] args) throws InterruptedException {
        A1 a1 = new A1();
        new Thread(()->{//普通方法,没有锁,不存在竞争资源,直接比同步方法先执行
            try {
                a1.sendSMS();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"send").start();

        new Thread(()->{a1.call();},"call").start();
        new Thread(()->{a1.normalFunc();},"normal").start();
    }


}
class A1 {

    public synchronized void call(){

        System.out.println("打电话");
    }
    public synchronized void sendSMS() throws InterruptedException {
        TimeUnit.SECONDS.sleep(10);
        System.out.println("发短信");
    }
    public void normalFunc(){
        System.out.println("我是个普通方法");
    }

}

4.两个对象两个锁,执行顺序是 没有sleep的先执行,有的后执行(由于没有资源的竞争,按照正常情况执行)
//执行结果打电话 我是个普通方法 发短信,由于打电话比普通方法先执行,所以先调用
//线程与线程之间竞争(按谁先调用,谁先) 锁与锁之间的竞争(谁先拿到锁,谁先执行)

 public class eightLockProblems { //线程之间资源的竞争,而不是同一个对象锁的竞争
	
    public static void main(String[] args) throws InterruptedException {
        //与上面的区别是资源类是2个了,但是是相同的对象
        A1 a1 = new A1();
        A1 a2 = new A1();   
        new Thread(()->{//锁之间没有资源竞争,所以不用等另外一个锁,另外一个锁直接执行
            try {
                a1.sendSMS();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"send").start(); //没有竞争

        new Thread(()->{a2.call();},"call").start();   //没有竞争
        new Thread(()->{a1.normalFunc();},"normal").start();
    }


}
class A1 {

    public synchronized void call(){

        System.out.println("打电话");
    }
    public synchronized void sendSMS() throws InterruptedException {
        TimeUnit.SECONDS.sleep(10);
        System.out.println("发短信");
    }
    public void normalFunc(){
        System.out.println("我是个普通方法");
    }

}

5.静态同步方法,只有一个对象 执行顺序是 sleep方法后是另外一个, 因为static修饰是Class模板全局唯一,所以两个同步静态方法用的是同一把锁,所以安装顺序执行
6.静态同步方法,只有两个对象, 还是顺序执行(和5一样的执行结果,无论new多少个都是锁Class对象)
//运行结果 我是个普通方法 发短信 打电话

public class eightLockProblems1 {

    public static void main(String[] args) throws InterruptedException {
        A2 a1 = new A2();
        A2 a2 = new A2();
        new Thread(()->{//无论执行多少次都是普通方法,发短信先执行,因为他先拿到a1这个锁对象(这里锁的是Class模板)
            try {
                a1.sendSMS();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"send").start();

        new Thread(()->{a2.call();},"call").start();
        new Thread(()->{a1.normalFunc();},"normal").start();
    }


}

class A2 {

    public static synchronized void call(){ //放在static区

        System.out.println("打电话");
    }
    public static synchronized void sendSMS() throws InterruptedException {
        TimeUnit.SECONDS.sleep(10);
        System.out.println("发短信");
//      类模板全局唯一在JVM里面讲的  Class<? extends A2> aClass = this.getClass();
    }
    public void normalFunc(){
        System.out.println("我是个普通方法");
    }

}

7.静态同步方法和普通同步方法,只有一个对象, 还是没有sleep先执行(代码如6)
8.静态同步方法和普通同步方法,只有两个对象, 还是没有sleep先执行(代码如6) (就还是Class竞争,谁先拿到,谁先执行,普通static不用锁竞争Class对象先执行)

//结果 : 我是个普通方法 发短信 我是个static同步方法(静态) 打电话(静态同步)文章来源地址https://www.toymoban.com/news/detail-475759.html

public class eightLockProblems1 {

    public static void main(String[] args) throws InterruptedException {
        A2 a1 = new A2();
        A2 a2 = new A2();
        new Thread(()->{//无论执行多少次都是发短信先执行,因为他先拿到a1这个锁对象(这里锁的是Class模板)
            try {
                a1.sendSMS();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"send").start();

        new Thread(()->{a2.call();},"call").start();
        new Thread(()->{a2.normalStaticFunc();},"normalstatic").start();//
        new Thread(()->{a1.normalFunc();},"normal").start();
    }


}

class A2 {

    public static synchronized void call(){

        System.out.println("打电话");
    }
    public static synchronized void sendSMS() throws InterruptedException {
        TimeUnit.SECONDS.sleep(10);
        System.out.println("发短信");
//      类模板全局唯一在JVM  Class<? extends A2> aClass = this.getClass();
    }
    public void normalFunc(){
        System.out.println("我是个普通方法");
    }

    public static synchronized void normalStaticFunc(){
        System.out.println("我是个static同步方法");
    }

}

到了这里,关于3.多线程之JUC并发编程0的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • JUC并发编程-线程和进程、Synchronized 和 Lock、生产者和消费者问题

    源码 + 官方文档 面试高频问! java.util 工具包、包、分类 业务:普通的线程代码 Thread Runnable Runnable 没有返回值、效率相比入 Callable 相对较低! 线程、进程,如果不能使用一句话说出来的技术,不扎实! 进程:一个程序,QQ.exe Music.exe 程序的集合; 一个进程往往可以包含多

    2024年01月20日
    浏览(51)
  • JUC并发编程学习(十三)ForkJoin

    什么是ForkJoin ForkJoin在JDK1.7,并发执行任务!大数据量时提高效率。 大数据:Map Reduce(把大任务拆分成小任务) ForkJoin特点:工作窃取 为什么可以取窃取其他线程的任务呢?因为这里面维护的都是 双端队列 (即队列的两端都可以取元素) ForkJoin操作 在java.util.concurrent下的接

    2024年02月05日
    浏览(61)
  • JUC并发编程学习笔记(十六)Volatile

    保证可见性 使用了volatile,即可保证它本身可被其他线程的工作内存感知,即变化时也会被同步变化。 不保证原子性 原子性:不可分割 线程A在执行任务时是不可被打扰的,也不能被分割,要么同时成功,要么同时失败。 每次结果也不一样。 如果不加Lock加synchronize

    2024年02月05日
    浏览(98)
  • JUC并发编程学习笔记(十五)JMM

    请你谈谈对Volatile的理解 Volatile是java虚拟机提供的 轻量级的同步机制 1、保证可见性 2、不保证原子性 3、禁止指令重排 什么是JMM JVM-java虚拟机 JMM-java内存模型,不存在的东西,概念!约定 关于JMM的一些同步的约定: 线程解锁前,必须把共享变量 立刻 刷回主存 线程加锁前,

    2024年02月05日
    浏览(50)
  • JUC并发编程学习笔记(八)读写锁

    ReadWriteLock ReadWriteLock只存在一个实现类那就是ReentrantReadWriteLock,他可以对锁实现更加细粒化的控制 读的时候可以有多个阅读器线程同时参与,写的时候只希望写入线程是独占的 Demo:

    2024年02月06日
    浏览(53)
  • JUC并发编程学习笔记(十九)原子引用

    带版本号的原子操作! 解决ABA问题,引入原子引用(乐观锁思想) AtomicStampedReference类解决ABA问题 所有相同类型的包装类对象之间值的比较全部使用equals方法比较 Integer使用了对象缓存机制,默认范围是-128至127,推荐使用静态工厂方法valueOf获取对象实例,而不是new,因为v

    2024年02月05日
    浏览(56)
  • JUC并发编程学习笔记(十四)异步回调

    Future设计的初衷:对将来的某个事件的结果进行建模 在Future类的子类中可以找到CompletableFuture,在介绍中可以看到这是为非异步的请求使用一些异步的方法来处理 点进具体实现类中,查看方法,可以看到CompletableFuture中的异步内部类,里面是实现的异步方法 以及一些异步方法

    2024年02月05日
    浏览(46)
  • JUC并发编程学习笔记(九)阻塞队列

    阻塞 队列 队列的特性:FIFO(fist inpupt fist output)先进先出 不得不阻塞的情况 什么情况下会使用阻塞队列:多线程并发处理、线程池 学会使用队列 添加、移除 四组API 方式 抛出异常 不抛出异常,有返回值 阻塞等待 超时等待 添加 add offer put offer(E e, long timeout, TimeUnit unit) 移

    2024年02月06日
    浏览(48)
  • java JUC并发编程 第六章 CAS

    第一章 java JUC并发编程 Future: link 第二章 java JUC并发编程 多线程锁: link 第三章 java JUC并发编程 中断机制: link 第四章 java JUC并发编程 java内存模型JMM: link 第五章 java JUC并发编程 volatile与JMM: link 第六章 java JUC并发编程 CAS: link 第七章 java JUC并发编程 原子操作类增强: link 第八章

    2024年02月10日
    浏览(48)
  • JUC并发编程学习笔记(六)Callable(简单)

    callable接口和runnable接口类似,都是为了执行另外一条线程而设计的,区别是Runnable不会返回结果也不会抛出异常。 1、可以有返回值 2、可以抛出异常 3、方法不同;run()/call(); Runnable 实现Runnable接口,重写run方法,无返回值 Callable 实现Callable接口,重写call方法,有返回值,可

    2024年02月06日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包