首页 > 编程语言 >Java实现新建三个线程,每个线程顺序打印5个数字,打印到100

Java实现新建三个线程,每个线程顺序打印5个数字,打印到100

时间:2023-04-02 16:22:39浏览次数:40  
标签:printABC Java Thread 打印 private num 线程 new

  • 方法一:synchronized + wait + notify
//三个线程循环打印数字,每个打印5个,打印数字到num class WaitNotifyABC{     private volatile int num = 0;//线程共享变量
    /**Object 和 this都可以对同步代码块加锁,但是this锁的是类的实例,如果该实例被他人拿走,     则本线程永远拿不到锁。Object也可以通过反射获取,但相比于this多一层保护。     为什么final?因为防止LOCK被重新赋值,相当于被其他线程抢走锁。*/     private static final Object LOCK = new Object();         private void printABC(int targetNum){         while(num <= 100){             synchronized(LOCK){                 /*用if会造成假唤醒的问题,如果if,执行了wait之后,被唤醒了就不会再判断if条件。                  while被唤醒之后会先执行while内的判断条件,避免在wait期间判断条件发生变化。*/                 while(num % 3 != targetNum){                     try {                         LOCK.wait();                     } catch (Exception e) {                         e.printStackTrace();                     }                 }                 for (int i = 0; i < 5; i++) {                     num++;                     if(num > 100){                         break;                     }                     System.out.println(Thread.currentThread().getName() + "-->" + String.valueOf(num));                 }                 LOCK.notifyAll();             }         }     }
    public static void main(String[] args) {         WaitNotifyABC waitNotifyABC = new WaitNotifyABC();         new Thread(() -> {             waitNotifyABC.printABC(0);         },"线程A").start();         new Thread(() ->{             waitNotifyABC.printABC(2);         },"线程B").start();         new Thread(() -> {             waitNotifyABC.printABC(1);         },"线程C").start();     } }
  •  方法二:Lock

Lock方法和synchronized方法相似,对同步代码块加锁,无论哪个线程拿到锁之后都需要满足num%3 == targetNum才能执行。

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

public class LockABC {
    private volatile int num = 0;
    private Lock lock = new ReentrantLock();

    private void printABC(int targetNum){
        while(num <= 100){
            lock.lock();
            if(num % 3 == targetNum){
                for (int i = 0; i < 5; i++) {
                    num++;
                    if(num > 100){
                        break;
                    }
                    System.out.println(Thread.currentThread().getName() + "-->" + String.valueOf(num));
                }
            }
            lock.unlock();
        }
    }
    public static void main(String[] args) {
        LockABC lockABC = new LockABC();
        new Thread(() -> {
            lockABC.printABC(0);
        },"线程A").start();
        new Thread(() -> {
            lockABC.printABC(2);
        },"线程B").start();
        new Thread(() -> {
            lockABC.printABC(1);
        },"线程C").start();
    }
    
}
  • 方法三:Lock+Condition
import java.net.CacheRequest;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class LockCondition {
    private volatile int num = 0;
    private Lock lock = new ReentrantLock();
    private Condition ca = lock.newCondition();
    private Condition cb = lock.newCondition();
    private Condition cc = lock.newCondition();

    private void printABC(int targetNum, Condition currentThread, Condition nextThread){
        while(num <= 100){
            lock.lock();
            try {
                while(num % 3 != targetNum){
                    if(num > 100){
                        break;
                    }
                    currentThread.await();
                }
                for (int i = 0; i < 5; i++) {
                    num++;
                    if(num > 100){
                        break;
                    }
                    System.out.println(Thread.currentThread().getName() + "-->" + String.valueOf(num));
                }
                nextThread.signal();
            } catch (Exception e) {
                e.printStackTrace();
            } finally{
                lock.unlock();
            }
        }
    }

    public static void main(String[] args) {
        LockCondition lockCondition = new LockCondition();
        new Thread(() -> {
            lockCondition.printABC(0, lockCondition.ca, lockCondition.cb);
        },"线程A").start();
        new Thread(() -> {
            lockCondition.printABC(2, lockCondition.cb, lockCondition.cc);
        },"线程B").start();
        new Thread(() -> {
            lockCondition.printABC(1, lockCondition.cc, lockCondition.ca);
        },"线程C").start();
    }
}
  • 方法四:Semophore
import java.util.concurrent.Semaphore;
public class SemaphoreABC {
    private volatile int num = 0;
    private Semaphore sa = new Semaphore(1);
    private Semaphore sb = new Semaphore(0);
    private Semaphore sc = new Semaphore(0);
    private void printABC(Semaphore currentThread, Semaphore nextThread){
        while(num <= 100){
            try {
                currentThread.acquire();
                for (int i = 0; i < 5; i++) {
                    num++;
                    if(num > 100){
                        break;
                    }
                    System.out.println(Thread.currentThread().getName() + "-->" + String.valueOf(num));
                }
                nextThread.release();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args) {
        SemaphoreABC semaphoreABC = new SemaphoreABC();
        new Thread(() -> {
            semaphoreABC.printABC(semaphoreABC.sa, semaphoreABC.sb);
        },"线程A").start();;
        new Thread(() -> {
            semaphoreABC.printABC(semaphoreABC.sb, semaphoreABC.sc);
        },"线程B").start();;
        new Thread(() -> {
            semaphoreABC.printABC(semaphoreABC.sc, semaphoreABC.sa);
        },"线程C").start();;
    }
}

 

标签:printABC,Java,Thread,打印,private,num,线程,new
From: https://www.cnblogs.com/iscanghai/p/17280261.html

相关文章

  • javascript VS python 变量作用域
    js中函数内部默认是可以读取到外部声明的变量,python不可以,必须使用关键字globalglobal必须在函数内部使用,用以内化函数外部变量。在函数外部是无法声明全局变量的,或者说所谓的全局变量在函数内部是不好使的,这还叫什么全局变量?应该叫局外变量。而global是内部跟局外变量建立一种......
  • 【Java 并发】【五】volatile怎么通过内存屏障保证可见性和有序性
    1 前言这节我们就来看看volatile怎么通过内存屏障保证可见性和有序性。2  保证可见性volatile修饰的变量,在每个读操作(load操作)之前都加上Load屏障,强制从主内存读取最新的数据。每次在assign赋值后面,加上Store屏障,强制将数据刷新到主内存。以volatileintx=0;线程A、B进行......
  • Java学习笔记(十四) maven1
    Maven介绍Maven是apache旗下的一个开源项目,是一款用于管理和构建java项目的工具,基于项目对象模型(POM)的概念,通过一小段信息来管理项目的构建Apache软件基金会,成立于1999年7月,是目前世界上最大的最受欢迎的开源软件基金会,也是一个专门为支持开源项目而生的非营利性......
  • Java学习笔记(十三) 前端基础2
    Ajax介绍概念:AsynchronousJavaScriptAndXML,异步的JavaScript和XML作用:数据交换:通过Ajax可以给服务器发送请求,并获取服务器响应的数据异步交互:可以在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术,如:搜索联想,用户名是否可用的校验等......
  • Java 函数式编程
    概述背景函数式编程的理论基础是阿隆佐·丘奇(AlonzoChurch)于1930年代提出的λ演算(LambdaCalculus)。λ演算是一种形式系统,用于研究函数定义、函数应用和递归。它为计算理论和计算机科学的发展奠定了基础。随着Haskell(1990年)和Erlang(1986年)等新一代函数式编程语言的诞生,......
  • Java学习笔记(十二) 前端基础1
    Web前端基础初识web前端网页由哪些部分组成?文字图片音频视频超链接等我们看到的网页,背后的本质是什么?程序员写的前端代码前端的代码是如何转换成用户眼中的网页的?通过浏览器转化(解析和渲染)成用户看到的网页浏览器中对代码进行解析渲染的部分,称为浏......
  • RxJava在业务系统中的实践
    在java的世界里由于大多数接口和API都是阻塞式的交互,进而影响到很多童靴的编程思想和编程习惯。因而,有一些专家讲java的编程模型是阻塞式模型(与Node.js区别大),不是没有道理的。从高性能的视角看,任何阻塞点都可能导致性能的退步。而响应式编程其天然就是非阻塞的,当数据准备完成后自动......
  • 面试题45(Java)-把数组排成最小的数(中等)
    题目:输入一个非负整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。示例1:输入:[10,2]输出:"102"示例 2:输入:[3,30,34,5,9]输出:"3033459"提示:0<nums.length<=100说明:输出结果可能非常大,所以你需要返回一个字符串而不......
  • Java基础语法
    用户交互Scanner实验importjava.util.Scanner;publicclassDome01{publicstaticvoidmain(String[]args){Scannerscanner=newScanner(System.in);System.out.println("使用Next方式接受");if(scanner.hasNext()){......
  • java——spring boot集成kafka——spring boot集成kafka
    引入依赖:  <dependency><groupId>org.springframework.kafka</groupId><artifactId>spring-kafka</artifactId></dependency>          编写配置文件:    erver:port:8080spring:kafka:bootstrap-se......