当前位置: 首页 > wzjs >正文

一起做业英语网站关键词规划师工具

一起做业英语网站,关键词规划师工具,网站怎么做配置文件夹,哪些网站是由wordpress做的多线程打印奇偶数,怎么控制打印的顺序 可以利用wait()和notify()来控制线程的执行顺序。 以下是一个基于这种方法的简单示例: public class PrintOddEven {private static final Object lock new Object();private static int count 1;private stat…

多线程打印奇偶数,怎么控制打印的顺序

可以利用wait()和notify()来控制线程的执行顺序。

以下是一个基于这种方法的简单示例:

public class PrintOddEven {private static final Object lock = new Object();private static int count = 1;private static final int MAX_COUNT = 10;public static void main(String[] args) {Runnable printOdd = () -> {synchronized (lock) {while (count <= MAX_COUNT) {if (count % 2 != 0) {System.out.println(Thread.currentThread().getName() + ": " + count++);lock.notify();} else {try {lock.wait();} catch (InterruptedException e) {e.printStackTrace();}}}}};Runnable printEven = () -> {synchronized (lock) {while (count <= MAX_COUNT) {if (count % 2 == 0) {System.out.println(Thread.currentThread().getName() + ": " + count++);lock.notify();} else {try {lock.wait();} catch (InterruptedException e) {e.printStackTrace();}}}}};Thread oddThread = new Thread(printOdd, "OddThread");Thread evenThread = new Thread(printEven, "EvenThread");oddThread.start();evenThread.start();}
}

在上面的示例中,通过一个共享的锁对象lock来控制两个线程的交替执行。一个线程负责打印奇数,另一个线程负责打印偶数,通过wait()和notify()方法来在两个线程之间实现顺序控制。当当前应该打印奇数时,偶数线程会进入等待状态,反之亦然。

  • 创建 3 个并发执行的线程,在每个线程的任务结束时调用 countDown 方法将计数器减 1。
  • 创建第 4 个线程,使用 await 方法等待计数器为 0,即等待其他 3 个线程完成任务。
import java.util.concurrent.CountDownLatch;public class CountDownLatchExample {public static void main(String[] args) {// 创建一个 CountDownLatch,初始计数为 3CountDownLatch latch = new CountDownLatch(3);// 创建并启动 3 个并发线程for (int i = 0; i < 3; i++) {final int threadNumber = i + 1;new Thread(() -> {try {System.out.println("Thread " + threadNumber + " is working.");// 模拟线程执行任务Thread.sleep((long) (Math.random() * 1000));System.out.println("Thread " + threadNumber + " has finished.");} catch (InterruptedException e) {e.printStackTrace();} finally {// 任务完成后,计数器减 1latch.countDown();}}).start();}// 创建并启动第 4 个线程,等待其他 3 个线程完成new Thread(() -> {try {System.out.println("Waiting for other threads to finish.");// 等待计数器为 0latch.await();System.out.println("All threads have finished, this thread starts to work.");} catch (InterruptedException e) {e.printStackTrace();}}).start();}
}

代码解释

  • 首先,创建了一个 CountDownLatch 对象 latch,并将其初始计数设置为 3。
  • 然后,使用 for 循环创建并启动 3 个线程。每个线程会执行一些工作(这里使用 Thread.sleep 模拟),在工作完成后,会调用 latch.countDown() 方法,将 latch 的计数减 1。
  • 最后,创建第 4 个线程。这个线程在开始时调用 latch.await() 方法,它会阻塞,直到 latch 的计数为 0,即前面 3 个线程都调用了 countDown() 方法。一旦计数为 0,该线程将继续执行后续任务。

#单例模型既然已经用了synchronized,为什么还要在加volatile?

使用 synchronized 和 volatile 一起,可以创建一个既线程安全又能正确初始化的单例模式,避免了多线程环境下的各种潜在问题。这是一种比较完善的线程安全的单例模式实现方式,尤其适用于高并发环境。

public class Singleton {private static volatile Singleton instance;private Singleton() {}public static Singleton getInstance() {if (instance == null) {synchronized (Singleton.class) {if (instance == null) {instance = new Singleton();}}}return instance;}
}

synchronized 关键字的作用用于确保在多线程环境下,只有一个线程能够进入同步块(这里是 synchronized (Singleton.class))。在创建单例对象时,通过 synchronized 保证了创建过程的线程安全性,避免多个线程同时创建多个单例对象。

volatile 确保了对象引用的可见性和创建过程的有序性,避免了由于指令重排序而导致的错误。

instance = new Singleton(); 这行代码并不是一个原子操作,它实际上可以分解为以下几个步骤:

  • 分配内存空间。
  • 实例化对象。
  • 将对象引用赋值给 instance

由于 Java 内存模型允许编译器和处理器对指令进行重排序,在没有 volatile 的情况下,可能会出现重排序,例如先将对象引用赋值给 instance,但对象的实例化操作尚未完成。

这样,其他线程在检查 instance == null 时,会认为单例已经创建,从而得到一个未完全初始化的对象,导致错误。

volatile 可以保证变量的可见性和禁止指令重排序。它确保对 instance 的修改对所有线程都是可见的,并且保证了上述三个步骤按顺序执行,避免了在单例创建过程中因指令重排序而导致的问题。

#3个线程并发执行,1个线程等待这三个线程全部执行完在执行,怎么实现?

可以使用 CountDownLatch 来实现 3 个线程并发执行,另一个线程等待这三个线程全部执行完再执行的需求。以下是具体的实现步骤:

  • 创建一个 CountDownLatch 对象,并将计数器初始化为 3,因为有 3 个线程需要等待。
  • 创建 3 个并发执行的线程,在每个线程的任务结束时调用 countDown 方法将计数器减 1。
  • 创建第 4 个线程,使用 await 方法等待计数器为 0,即等待其他 3 个线程完成任务。
import java.util.concurrent.CountDownLatch;public class CountDownLatchExample {public static void main(String[] args) {// 创建一个 CountDownLatch,初始计数为 3CountDownLatch latch = new CountDownLatch(3);// 创建并启动 3 个并发线程for (int i = 0; i < 3; i++) {final int threadNumber = i + 1;new Thread(() -> {try {System.out.println("Thread " + threadNumber + " is working.");// 模拟线程执行任务Thread.sleep((long) (Math.random() * 1000));System.out.println("Thread " + threadNumber + " has finished.");} catch (InterruptedException e) {e.printStackTrace();} finally {// 任务完成后,计数器减 1latch.countDown();}}).start();}// 创建并启动第 4 个线程,等待其他 3 个线程完成new Thread(() -> {try {System.out.println("Waiting for other threads to finish.");// 等待计数器为 0latch.await();System.out.println("All threads have finished, this thread starts to work.");} catch (InterruptedException e) {e.printStackTrace();}}).start();}
}

代码解释

  • 首先,创建了一个 CountDownLatch 对象 latch,并将其初始计数设置为 3。
  • 然后,使用 for 循环创建并启动 3 个线程。每个线程会执行一些工作(这里使用 Thread.sleep 模拟),在工作完成后,会调用 latch.countDown() 方法,将 latch 的计数减 1。
  • 最后,创建第 4 个线程。这个线程在开始时调用 latch.await() 方法,它会阻塞,直到 latch 的计数为 0,即前面 3 个线程都调用了 countDown() 方法。一旦计数为 0,该线程将继续执行后续任务。

#假设两个线程并发读写同一个整型变量,初始值为零,每个线程加 50 次,结果可能是什么?

在没有任何同步机制的情况下,两个线程并发对同一个整型变量进行 50 次加 1 操作,最终结果可能是 100,也可能小于 100,最坏的结果是 50,也就是最终的结果可能是在 [50, 100] 。

小于 100 情况的分析,由于对整型变量的 num++ 操作不是原子操作,它实际上包含了三个步骤:读取变量的值、将值加 1、将新值写回变量。在多线程环境下,可能会出现线程安全问题。例如,线程 1 和线程 2 同时读取了变量的当前值,然后各自将其加 1,最后都将相同的新值写回变量,这就导致了一次加 1 操作的丢失。这种情况会多次发生,最终结果就会小于 100。

import java.util.concurrent.atomic.AtomicInteger;public class AtomicIntegerAddition {private static AtomicInteger num = new AtomicInteger(0);public static void main(String[] args) throws InterruptedException {Thread thread1 = new Thread(() -> {for (int i = 0; i < 50; i++) {num.incrementAndGet();}});Thread thread2 = new Thread(() -> {for (int i = 0; i < 50; i++) {num.incrementAndGet();}});thread1.start();thread2.start();thread1.join();thread2.join();System.out.println("最终结果: " + num.get());}
}

第二种方式:通过 synchronized 关键字或 ReentrantLock 确保操作的互斥性,代码如下:

public class SynchronizedAddition {private static int num = 0;private static final Object lock = new Object();public static void main(String[] args) throws InterruptedException {Thread thread1 = new Thread(() -> {for (int i = 0; i < 50; i++) {synchronized (lock) {num++;}}});Thread thread2 = new Thread(() -> {for (int i = 0; i < 50; i++) {synchronized (lock) {num++;}}});thread1.start();thread2.start();thread1.join();thread2.join();System.out.println("最终结果: " + num);}
}
http://www.dtcms.com/wzjs/502008.html

相关文章:

  • 什么值得买 网站开发网站推广搜索
  • 电子商务网站建设与运营百度图片搜索引擎入口
  • 用flash做的网站欣赏全网热搜榜第一名
  • 长沙房产交易中心官网青岛seo网络推广
  • 漯河网站建设公司临沂seo推广
  • 哪些网站是响应式的澳门seo推广
  • 中山网站建设是什么今日最新新闻
  • 织梦dede做网站的优点百度旗下产品
  • 建设银行网站查询密码googleseo排名公司
  • 做网站有什么用对网站和网页的认识
  • 公司的网站是什么网站宣传文案范例
  • 网站怎么申请官网网站分析报告范文
  • 百度主机做视频网站怎么样福州短视频seo推荐
  • 怎么找人做网站啊seo竞价推广
  • 政务网站安全建设工作计划网站测试
  • 有什么展厅设计做的好的网站seo排名优化首页
  • 中科建建设发展有限公司网站怎么宣传自己的产品
  • 网站建设 amp 金手指排名效果好关键词营销优化
  • 深度网营销型网站建设公司怎么样swot分析
  • 电子商务前景怎么样学seo哪个培训好
  • 网站使用功能介绍是用什么软件做的企业线上培训平台有哪些
  • 苏州三石网络科技有限公司知乎关键词排名优化工具
  • 网站建设对企业经营昆明网络营销
  • 成都网站制作在线媒体公关
  • 公司商城网站建设中国seo谁最厉害
  • 云南网站建设seo自学教程seo免费教程
  • 网站建设 资讯动态代写文章接单平台
  • 湖南网站建设的公司排名北京网站优化服务商
  • 视觉冲击力的网站设计企业网站优化外包
  • 大庆百度做网站多少钱seo服务的内容