返回顶部
首页 > 资讯 > 精选 >Java线程中关键字和方法的示例分析
  • 518
分享到

Java线程中关键字和方法的示例分析

2023-06-29 08:06:03 518人浏览 安东尼
摘要

这篇文章主要为大家展示了“Java线程中关键字和方法的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Java线程中关键字和方法的示例分析”这篇文章吧。一、volatile关键字1,vol

这篇文章主要为大家展示了“Java线程中关键字和方法的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Java线程中关键字和方法的示例分析”这篇文章吧。

一、volatile关键字

1,volatile 能保证内存可见性

代码在写入 volatile 修饰的变量的时候

        改变线程工作内存中volatile变量副本的值

        将改变后的副本的值从工作内存刷新到主内存

代码在读取 volatile 修饰的变量的时候

        从主内存中读取volatile变量的最新值到线程的工作内存中

        从工作内存中读取volatile变量的副本

 static class Counter{        public int flag = 0;    }        public static void main(String[] args) {        Counter counter = new Counter();        Thread t1 = new Thread(){            @Override            public void run() {                while (counter.flag == 0){                 }                System.out.println("循环结束");            }        };        t1.start();        Thread t2 = new Thread(){                Scanner scanner = new Scanner(System.in);                System.out.println("请输入一个整数:");                counter.flag = scanner.nextInt();        t2.start();

Java线程中关键字和方法的示例分析

预期的结果是:

线程1会先进入循环状态,线程2读取一个用户输入的整数。随着用户的输入一个非0的整数之后,线程1就会终止。

实际效果:

线程2输入完毕后,线程1循环并未结束

2,编译器优化问题

线程1的核心代码中,循环其实啥也没干,反复快速的执行循环条件中的比较操作。

        先从内存中读取flag的值到CPU中

        在CPU中比较这个值和0的关系

编译器判定这个逻辑中循环没有干啥事,只是频繁的读取内存而已,于是编译器就把读内存的操作优化了,第一次把内存中的数据督读到CPU之后,后序的内存并不是真正的从内存中读,而是直接从刚在的CPU中读数据

编译器认为flag没有改动,其实只是在当前线程中没有改动,编译器就不能感知到其他的线程对flag进行了修改

static class Counter{        public  volatile  int flag = 0;    }     public static void main(String[] args) {        Counter counter = new Counter();        Thread t1 = new Thread(){            @Override            public void run() {                while (counter.flag == 0){                }                System.out.println("循环结束");            }        };        t1.start();        Thread t2 = new Thread(){                Scanner scanner = new Scanner(System.in);                System.out.println("请输入一个整数:");                counter.flag = scanner.nextInt();        t2.start();

Java线程中关键字和方法的示例分析

加了volatile之后,对这个内存的读取操作肯定是从内存中来读

不加volatile的时候,读取操作可能不是从内存中读取,从CPU上读取旧值,这都是不确定的

volatile 和 synchronized 有着本质的区别.

synchronized 能够保证原子性, volatile 保证的是内存可见性

synchronized 既能保证原子性, 也能保证内存可见性.

二、wait 和 notify

由于线程之间是抢占式执行的, 因此线程之间执行的先后顺序难以预知. 但是实际开发中有时候我们希望合理的协调多个线程之间的执行先后顺序

1,wait()方法

wait 做的事情:

使当前执行代码的线程进行等待. (把线程放到等待队列中)

释放当前的

满足一定条件时被唤醒, 重新尝试获取这个锁.

wait 要搭配 synchronized 来使用. 脱离 synchronized 使用 wait 会直接抛出异常.

wait 结束等待的条件:

其他线程调用该对象的 notify 方法.

wait 等待时间超时 (wait 方法提供一个带有 timeout 参数的版本, 来指定等待时间).

其他线程调用该等待线程的 interrupted 方法, 导致 wait 抛出 InterruptedException 异常.

public static void main(String[] args) throws InterruptedException {        Object object = new Object();        synchronized (object){            System.out.println("等待前");            object.wait();            System.out.println("等待后");        }    }

Java线程中关键字和方法的示例分析

就相当于一个人去ATM上取钱,发现ATM中没钱,然后阻塞等待(不参与后续锁的竞争)——wait

等到银行的工作人员来送钱,你可以取钱了——notify

2,notify()方法

notify 方法是唤醒等待的线程.

        方法notify()也要在同步方法或同步块中调用,该方法是用来通知那些可能等待该对象的对象锁的其它线程,对其发出通知notify,并使它们重新获取该对象的对象锁。

        如果有多个线程等待,则有线程调度器随机挑选出一个呈 wait 状态的线程。(并没有 "先来后到")

        在notify()方法后,当前线程不会马上释放该对象锁,要等到执行notify()方法的线程将程序执行 完,也就是退出同步代码块之后才会释放对象锁。

 public static void main(String[] args) {        Object locker = new Object();         Thread t1 = new Thread(){            @Override            public void run() {                synchronized (locker){                    while (true){                        System.out.println("wait开始");                        try {                            locker.wait();                        } catch (InterruptedException e) {                            e.printStackTrace();                        }                        System.out.println("wait结束");                    }                }            }        };        t1.start();        Thread t2 = new Thread(){                Scanner scanner = new Scanner(System.in);                System.out.println("输入一个整数,继续执行");                int num = scanner.nextInt();                    System.out.println("notify开始");                    locker.notify();                    System.out.println("notify结束");        t2.start();    }

Java线程中关键字和方法的示例分析

Java线程中关键字和方法的示例分析

 3,notifyAll()方法

notify方法只是唤醒某一个等待线程.

使用notifyAll方法可以一次唤醒所有的等待线程.

以上是“Java线程中关键字和方法的示例分析”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网精选频道!

--结束END--

本文标题: Java线程中关键字和方法的示例分析

本文链接: https://lsjlt.com/news/323770.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Java线程中关键字和方法的示例分析
    这篇文章主要为大家展示了“Java线程中关键字和方法的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Java线程中关键字和方法的示例分析”这篇文章吧。一、volatile关键字1,vol...
    99+
    2023-06-29
  • Java线程中的关键字和方法示例详解
    目录一、volatile关键字1,volatile 能保证内存可见性2,编译器优化问题二、wait 和 notify1,wait()方法2,notify()方法 3,not...
    99+
    2024-04-02
  • Java关键字final的示例分析
    小编给大家分享一下Java关键字final的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、常见问题所有的final修饰的字段都是编译期常量吗如何理解p...
    99+
    2023-06-15
  • JAVA并发中VOLATILE关键字的示例分析
    小编给大家分享一下JAVA并发中VOLATILE关键字的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!并发编程中的三个概念:1.原子性在Java中,对基本...
    99+
    2023-06-15
  • java基础之关键字的示例分析
    这篇文章将为大家详细讲解有关java基础之关键字的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。1、static关键字1.1 使用static关键字定义属性在讲解static定义属性操作之前,首先...
    99+
    2023-06-20
  • Java Web关键字填空示例分析
    今天小编给大家分享一下Java Web关键字填空示例分析的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。(1)在Te...
    99+
    2023-06-30
  • java中进程和线程的示例分析
    小编给大家分享一下java中进程和线程的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!为什么会有进程在简单的批处理操作系统中,作业时串行执行的,即一个作业...
    99+
    2023-06-20
  • defer关键字、panic和recover的示例分析
    这篇文章给大家介绍defer关键字、panic和recover的示例分析,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。defer关键字defer关键字可以让函数或语句延迟到函数语句块的...
    99+
    2024-04-02
  • Java并发编程之关键字volatile的示例分析
    这篇文章给大家分享的是有关Java并发编程之关键字volatile的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、作用被 volatile 修饰的变量保证了不同线程对该变量操作的内存可见性禁止指令重排...
    99+
    2023-06-15
  • Java中线程的示例分析
    这篇文章主要介绍了Java中线程的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。什么是进程?电脑中时会有很多单独运行的程序,每个程序有一个独立的进程,而进程之间是相互...
    99+
    2023-06-25
  • JAVA面试题之static关键字的示例分析
    这篇文章给大家分享的是有关JAVA面试题之static关键字的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。问题面试官Q1:请说说static关键字,你在项目中是怎么使用...
    99+
    2024-04-02
  • java中多线程的示例分析
    这篇文章主要介绍了java中多线程的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。java多线程并发与并行:并行: 指两个或多个事件在同一时刻发生 ( 同时发生 ) ...
    99+
    2023-06-20
  • Java中线程池的示例分析
    小编给大家分享一下Java中线程池的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!Java线程池线程的缺点:线程的创建它会开辟本地方法栈、JVM栈、程序计...
    99+
    2023-06-20
  • java编程中abstract类和方法的示例分析
    小编给大家分享一下java编程中abstract类和方法的示例分析,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!抽象类和抽象方法常用知识点:(1)抽象类作为被继承类,子类必须实现抽象类中的所有抽象方法,除非子类也为抽象类。...
    99+
    2023-05-30
    java abstract
  • Java程序中多线程的示例分析
    这篇文章主要介绍了Java程序中多线程的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。  为什么会排队等待?  下面的这个简单的 Java 程序完成四项不相关的任务。...
    99+
    2023-06-03
  • Java线程池的示例分析
    小编给大家分享一下Java线程池的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!为什么需要线程池我们知道创建线程的常用方式就是 new Thread() ...
    99+
    2023-06-22
  • Java多线程的示例分析
    这篇文章给大家分享的是有关Java多线程的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。线程的创建继承Thread实现Runnable实现Callable使用继承Thread类来开发多线程的应用程序在设计...
    99+
    2023-06-20
  • java线程编程的示例分析
    这篇文章给大家分享的是有关java线程编程的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。线程基础◆线程(thread)其实是控制线程(thread of control)的缩写.每一个线程都是独立的,因...
    99+
    2023-06-03
  • Java中方法的示例分析
    这篇文章给大家分享的是有关Java中方法的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。什么是方法例如:System.out.println();其结构为-->类.对象.方法;其含义为-->调...
    99+
    2023-06-20
  • Node.js中进程和线程的示例分析
    这篇文章给大家分享的是有关Node.js中进程和线程的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。进程与线程是一个程序员的必知概念,面试经常被问及,但是一些文章内容只是讲讲理论知识,可能一些小伙伴并没有...
    99+
    2023-06-15
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作