Java线程初步

FactoryTalk View Studio SE 与 Studio 5000 通信配置:3步建立标签链接与仿真测试 本文详细介绍了FactoryTalk View Studio SE与Studio 5000的高效通信配置方法,通过3步建立标签链接与仿真测试,实现工业自动化系统中HMI与PLC的无缝集成。涵盖工程环境准备、通信通道建立、离线仿真验证等关键步骤,并提供了性能优化和故障排查的实用技巧,助力工程师快速部署稳定可靠的工业控制系统。 阅读详情

先上一个实例:两个人各自有3000块钱,要分别存入同一个账户,但是每个人每次只能存入1000块,要求每次存完钱后打印账户余额。

package thread.first;
//使用继承的方式实现多线程
class People extends Thread{
    //两个属性必须设置为静态的,让不同的对象共用
    private static int money;
    private static Object object=new Object();
    public void run(){
        show();
    }
    public void show(){
        synchronized (object) {//同步代码块,不同的对象共用一把锁
            for(int i=3;i>0;i--){
                money+=1000;
                System.out.println(Thread.currentThread().getName()+":"+money);
            }
        }
    }
}
public class TestCount {
    public static void main(String[] args) {
        People man1=new People();
        People man2=new People();
        man1.start();
        man2.start();

    }
}
/* 输出结果:
 * Thread-0:1000
 * Thread-0:2000
 * Thread-0:3000
 * Thread-1:4000
 * Thread-1:5000
 * Thread-1:6000
*/

使用继承的方式有很多缺点,具体对比实现的方式,上代码:

package thread.first;
//实现的方式实现多线程
class Man implements Runnable{
    private int money=0;//不需要定义为static,多线程共用一个对象
    public synchronized void run(){//同步方法,因为多线程共用一个对象,所以锁为当前对象
        for(int i=3;i>0;i--){
            money+=1000;
            System.out.println(Thread.currentThread().getName()+":"+money);
        }
    }
}

public class TestCount {

    public static void main(String[] args) {
        Man people=new Man();
        //只需要一个对象
        Thread t1=new Thread(people);
        Thread t2=new Thread(people);

        t1.start();
        t2.start();
    }
}
/* 
*/

第三种实现方式是实现Callable接口,个人理解这种方式最大的特别之处是有返回值。

package com.thread.demo;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class TestCallableThread {
//  public static void main(String[] args) throws InterruptedException, ExecutionException {
//      ThreadDemo threadDemo = new ThreadDemo();
//      FutureTask<Integer> result = new FutureTask<>(threadDemo);
//      new Thread(result).start();
//      System.out.println(result.get().toString());
//  }
    public static void main(String[] args) {
        Woman woman = new Woman();
        FutureTask<Object> futureTask1 = new FutureTask<>(woman);
        FutureTask<Object> futureTask2 = new FutureTask<>(woman);
        new Thread(futureTask1).start();
        new Thread(futureTask2).start();

    }
}

class Woman implements Callable<Object>{

    private int money=0;//不需要定义为static,多线程共用一个对象

    @Override
    public synchronized Object call() throws Exception {
        for(int i=3;i>0;i--){
            money+=1000;
            System.out.println(Thread.currentThread().getName()+":"+money);
        }
        return null;
    }

}



class ThreadDemo implements Callable<Integer>{

    @Override
    public Integer call() throws Exception {
        System.out.println("ThreadDemo Call");
        return 23;
    }

}

线程通信,最经典的例子就是生产者消费者模型,上代码:

package thread.first;
class Clerk{//店员类,用来协调生产者和消费者
    int productNum;//商品数目,假设店里最多放入5个商品
    public synchronized void add(){
        if(productNum<5){
            try {
                Thread.currentThread().sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            productNum++;
            System.out.println("生产者生产了第"+productNum+"个商品");
            notifyAll();
        }else{//如果等于5了,让生产者等待
            try {
                wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    public synchronized void reduce(){
        if(productNum>0){
            try {
                Thread.currentThread().sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("消费者消费了第"+productNum+"个商品");
            productNum--;
            notifyAll();
        }else{//没有商品了,让消费者等待
            try {
                wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}
class Producer implements Runnable{
    Clerk clerk;
    public Producer(Clerk clerk){
        this.clerk=clerk;
    }
    public void run(){
        //System.out.println("生产者生产产品");
        while(true){
            clerk.add();
        }
    }
}
class Customer implements Runnable{
    Clerk clerk;
    public Customer(Clerk clerk){
        this.clerk=clerk;
    }
    public void run(){
        //System.out.println("消费者消费产品");
        while(true){
            clerk.reduce();
        }
    }
}
public class TestProCustomer {
    public static void main(String[] args) {
        Clerk clerk=new Clerk();
        Producer producer1=new Producer(clerk);
        Producer producer2=new Producer(clerk);
        Customer customer1=new Customer(clerk);
        Customer customer2=new Customer(clerk);

        Thread t1=new Thread(producer1);
        Thread t2=new Thread(producer2);
        Thread t3=new Thread(customer1);
        Thread t4=new Thread(customer2);

        t1.start();
        t2.start();
        t3.start();
        t4.start();
    }

}
/*生产者生产了第1个商品
生产者生产了第2个商品
消费者消费了第2个商品
消费者消费了第1个商品
生产者生产了第1个商品
生产者生产了第2个商品
生产者生产了第3个商品
生产者生产了第4个商品
生产者生产了第5个商品
消费者消费了第5个商品
消费者消费了第4个商品
*/

关于线程池的使用以及源码分析,请参考这篇写的极好的博客。

操作系统课设-生产者消费者问题.zip 一、设计要求 设计一个模拟仿真“生产者-消费者”问题的解决过程及方法的程序。 主要内容是P、V操作过程的设计与实现。生产消费者问题是操作系统设计中经常遇到的问题。多个生产者和消费者线程访问在共享内存中的环形缓冲。生产者生产产品并将它放入环形缓冲,同时消费者从缓冲中取出产品并消费。当缓冲区满时生产者阻塞并且当缓冲区有空时生产者又重新工作。类似的,消费者当缓冲区空时阻塞并且当缓冲区有产品时又重新工作。显然,生产者和消费者需要一种同步机制以协调它们的工作。 二、系统功能 本程序模拟实现了“生产者-消费者”问题的解决过程,用图形界面动态演示了P、V操作过程以及生产者、消费者进程之间的工作流程。 本程序使用的算法是典型的P、V操作使用信号量解决“生产者-消费者”问题。 本程序在界面上使用了Java的swing接口函数,用矩形条表示生产者进程中待生产的产品,并设置了三个分区分别表示生产者进程待生产的产品、公共缓冲池中已生产的产品和消费者进程已消费的产品,以动画的效果动态演示了待生产产品变成消费者进程中已消费产品的过程,以及在这一过程中生产者进程和消费者进程协调工作的过程。在程序运行过程中使用了两个生产者线程和两个消费者线程并发工作,并使用了线程随机休眠的策略,即每个线程在完成一次生产过程或消费过程后随机休眠1至10秒钟。这一策略能保证生产者和消费者之间的运行顺序被打破,从而产生生产产品和消费产品之间的矛盾(即没有产品可消费的情况下消费者试图向公共缓冲池取产品消费、公共缓冲池里的产品已满的情况下生产者试图生产产品放入缓冲池)。因为生产者生产产品和消费者消费产品都是随机的,所以产生的矛盾也是不可预知的,在这种情况下,才能检验所使用的算法是否健壮高效。而本程序正是基于这种思想设计出来的,用来模拟生产者消费者问题的解决过程。 本程序在运行时提供友好的交互界面,且操作简单,在模拟过程中各种情况有相应文字提示,并伴有相应的图像变化,如:当没有产品可消费的情况下消费者试图向公共缓冲池取产品消费,消费者进程阻塞,公共缓冲池随之变成红色,文字提示框内显示warning: it's empty!Consumer is block;当缓冲池已满而生产者试图生产产品并向缓冲池放入产品时,生产者进程阻塞,公共缓冲池里的每一个产品变成黄色,问题提示框显示warning: it's full!Producer is block。整个模拟过程通俗易懂,利于理解,能很好的帮助使用者加强生产者消费者问题的理解。 立即下载

相关推荐

LabVIEW波形图表时间轴设置:三种方法实现横坐标显示日期时间

在数据采集与设备监控场景中,波形图表的横坐标默认显示采样点序号而非日期时间,这给工程师分析历史数据带来不便。理解时间标识(Timestamp)的本质——一个自1904年起算的双精度秒数,是解决问题的关键。时间轴设置既是显示格式问题,更是数据层与显示层的协同设计。通过属性节点动态生成刻度标签、将时间标识数组直接作为X轴数据、或使用波形数据(Waveform)类型绑定t0与dt,分别适用于固定点数显示、非等间隔事件记录和等间隔连续采样等不同需求。合理选择方案并注意缓冲区预分配与时间连续性处理,可让波形图表准确呈

weixin_33416697的博客 253

Java多线程生产者和消费者实现

一、概述 首先,我们需要明白生产者和消费者模型是为了解决多线程之间通信而产生的。其次,需要了解实现线程间通信用到了哪些知识点。先来看一张生产者和消费者模型图: 这里有四个对象,一个是生产者,一个是消费者,一个是容器,最后还有一个是需要生产的商品,虽然在图上没有体现出来。刚开始容器里面没有商品,消费者等待,生产者开始生产,当容器里面有商品了,生产者通知消费者去消费,如果生产的速度比较快,容器...

不将就 655

【逆强化学习-1】学徒学习(Apprenticeship Learning)

逆强化学习算法1:学徒学习。算法原理+算法步骤+代码+仿真:一个基于gym的小车上山的仿真。附赠学徒学习+Q-Table及学徒学习+DQN的全套代码。

体会编程语言独到的美 7493

基于Java Swing的生产者消费者多道程序设计

基于Java Swing的生产者消费者多道程序设计 一、介绍 最近操作系统布置了一次多道同步互斥程序编程设计体验的作业,抱着水一水心态的我试了一下用GUI界面实现生产者消费者问题的模拟,发现根本做不出来,同专业的同学有用VS MFC做的,有用C#做的,也有人用Eclipse做的Web项目,还有用JAVA AWT做的,可能只有我用Java Swing做的。后来才知道AWT有插件,才明白他们不懂我手动...

PANDA 955

.NET适配HarmonyOS进展 1. 前言

目前国产化系统浪潮下,适配鸿蒙是中国软件大势所趋,.NET作为最适合开发客户端语言之一,适配鸿蒙系统(HarmonyOS Next)是目前.NET开发者最关心的事情。我目前业余时间正在移植Avalonia到HarmonyOS,去年在.NET Conf CN上分享过,目前又取得一点进展,所以本文把所有问题进行整合与大家进行分享。

2301_76476890的博客 1461

Calibre PEX提参实战:如何用hcell和xcell文件精准屏蔽模块(附避坑指南)

本文深入解析Calibre PEX工具中hcell与xcell文件的协同工作机制,提供模块级寄生参数提取方案。通过实战案例和避坑指南,帮助工程师精准屏蔽已验证IP模块,提升仿真效率和数据一致性,适用于65nm以下工艺节点的复杂SoC设计。

weixin_29275257的博客 626

生产者和消费者问题(Java)

生产者和消费者问题代码Java语言 package ProducerConsumerPackage; import javax.swing.JTextArea; /** 定义临界资源:缓冲队列 **/ public class Buffers { JTextArea ta; static final int productBufferNum = 10; // 缓冲单元数 ProductBuffer pBuffer[] = new ProductBuffer[productBufferNum]; /

Qxxchampion的博客 393

从零构建AI Agent集群:Docker Compose与Nginx部署实战

在AI应用开发领域,微服务架构和容器化部署已成为提升开发效率和系统可维护性的关键技术。Docker Compose作为容器编排工具,能够将多个独立服务(如Node.js、Python应用)及其依赖(数据库、缓存)封装在隔离环境中,并通过统一配置文件定义服务间的网络与依赖关系,实现一键启停。Nginx作为反向代理,则提供了统一的网络入口、请求路由和负载均衡能力,是构建高可用Web应用的基石。这种组合技术方案的价值在于,它能将复杂的AI系统(如工作流引擎、对话Agent、技能库)的部署运维复杂度大幅降低,使得开

weixin_27028523的博客 638

java线程对应操作系统线程初步探索

linux操作系统的线程控制: yum -y install man-pages man pthread_create int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg); 参数 pthread_t *thread 传出参数,调用之后会传出被创建线程的id 定义 pthr

豆腐蛋 266

从Microchip SDK到STM32实战:手把手教你移植LAN9252 EtherCAT从站驱动(含EEPROM配置避坑)

本文详细介绍了如何将Microchip SDK中的LAN9252 EtherCAT从站驱动移植到STM32F407平台,包括FSMC接口配置、中断处理适配和EEPROM配置等关键步骤。通过实战指南和避坑技巧,帮助开发者快速实现高性能EtherCAT从站设备的开发,适用于工业自动化领域。

weixin_29197835的博客 446

【BlueDroid】蓝牙音乐协议分析之A2DP和AVRCP连接流程(超详细)

AVCTP协议描述了蓝牙设备间Audio/Video的控制信号交换的格式和机制,他是一个总体的协议,具体的控制信息由其指定的协议(AVRCP)实现,AVCTP协议本身只指定控制Command和Response的总体的格式;这个过程中对应了Event中的btavrcp_play_status_changed_callback和btavrcp_play_position_changed_callback;上述为AVCTP-Control建立L2CAP连接的Command,对应H4的Sent (0x00);

风云说通信 7313

Java之线程初步

====================================================== 注:重要!程序员如何有效的放松身心!下班后做什么? ====================================================== 【定义线程】 1、扩展java.lang.thread类,实现run()方法,直接调用start()方法。 2、实

81

以 Joule 驱动的生成式开发:把需求文档直接变成可运行的 SAP 应用

摘要:SAP BTP的AI助手Joule正在改变开发方式,支持从自然语言描述自动生成数据模型、服务、UI及测试代码。在SAP Business Application Studio中,Joule能根据业务需求生成结构化代码,并提供代码补全、重构、解释等功能。开发者需注意避免上传敏感数据,并对AI生成的代码进行人工审核。Joule特别针对ABAP开发进行了优化,提供符合SAP规范的代码建议,帮助迁移遗留系统。此外,它还能快速生成CAP项目原型,但所有AI生成内容都需经过严格测试验证。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 340

Java 线程初步

Java线程初步线程的相关定义进程线程进程与线程的实例线程运行实例多线程含义使用方法多线程运行过程中的易错点多线程同时对一个变量进行修改 线程的相关定义 进程 启动一个程序、运行的这一个过程成为一个进程。 线程 启动一个程序后,在该程序里做各种事情,各自分工不同的过程,每个过程叫做一个线程。 进程与线程的实例 1、启动了eclipse程序,该过程可以称为是一个进程(相对于系统来说),然后再ecli...

Aczy156的博客 326

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Java多线程初步掌握

文章目录线程的基础知识理解线程和进程的区别和联系两种创建线程的方式线程的生命周期线程死亡的几种情况控制线程的常用方法线程同步的概念和必要性使用synchronized控制线程同步使用Lock对象控制线程同步使用Object提供的方法实现线程通信使用条件变量实现线程通信使用管道流实现线程通信实现Callable接口创建线程线程池的功能和用法ThreadLocal类的功能和用法使用线程安全的集合类 线...

炎溟墨的博客 1102

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Java线程池初步解读

好好学习,天天向上 本文已收录至我的Github仓库DayDayUP:github.com/RobodLee/DayDayUP,欢迎Star 几个月前,写了一篇《Java并发学习(一):进程和线程》,其中埋了一个坑,说我不会用线程池,毕竟像咱们这种小学生,在学校做的小破项目也用不到线程池这种高大上的东西,所以一直也没学。但是最近不是准备出去打工了嘛,所以线程池还是要学一下的,不然到时候面试官一问,啥也不会大眼瞪小眼,不是很尴尬吗~~~。这不,这两天看了下线程池,搞篇文章总结一下线程池的基本知识????

Robod的博客 2904

Java的四种线程初步认识

Java通过Executors提供四种线程池,分别为: newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。 newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。 newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。

wsly123321的专栏 413

Java多线程初步

写在前面: 笔者才疏学浅,本文参考网上众多前辈大佬的文章,整理引用了部分观点及内容,加之笔者些许愚见糅合而成。 如有侵权还请联系笔者,必在第一时间处理 若是有写的有误,还请务必指出,感激不敬 文章目录为何要用多线程[^1]多线程带来的问题:线程安全如何使得线程安全:线程通信及同步单个线程的说明线程的生命周期如何切换线程状态:Thread类部分常用函数中断机制[^6]如何实现一个线程守护线程线程优先级[^10] 为何要用多线程1 对于多核处理器来说:提高CPU利用率 如果在多核处理器上运行单线程程序,会.

突破吧!次元壁 848

【一】Java线程初步了解

Java线程 一、进程与线程 进程是指一个内存中运行的应用程序,每个进程都有自己独立的一块内存空间,即进程空间或(虚空间)。进程不依赖于线程而独立存在,一个进程中可以启动多个线程。比如在Windows系统中,一个运行的exe就是一个进程。 线程是指进程中的一个执行流程,一个进程中可以运行多个线程。比如java.exe进程中可以运行很多线程。线程总是属于某个进程,线程没有自己的虚拟地址空间,与进程内的其他线程一起共享分配给该进程的所有资源。 二、线程实现方式 (一)继承 Thread 类 public cla

Zack_tzh的博客 2万+

Java线程初步认识.

什么是线程,说起线程必须要提到进程,所谓的进程就是一个独立的应用程序,打开我们的任务管理器,我们可以看到很多的进程 进程是每一个独立的程序在计算机上面的一次执行活动.一个独立运行的程序我们称之为一个进程.比如我们的QQ,浏览器等等,都算是一个进程。一个进程就可以包含多个线程,比如我们的QQ可以聊天,听音乐,以及下载文件等等。这些线程共享进程的资源。这里的资源包含了内存资源以及数据资源.在实际的开...

hackerbaseing的博客 146

初步了解java线程

一:线程的创建方式 1.继承Thread类,重写其中的run()方法: 实现线程的第一种方式: 1.创建一个Thread的子类 2.在子类中重写Thread类中的run方法,设置线程任务 3.创建Thread的子类对象 4.调用Thread中的start方法,开启新的线程,执行run方法 2.创建Runnable接口的实现类 1.创建Runnable接口的实现类 2.实现类中重写Run...

weixin_44579568的博客 113

初步掌握JAVA线程

本人也是刚入门此行业,如果有总结的不对的地方,请联系我,我会抓紧更改。

2301_78418531的博客 100

Java线程池初步理解

前言:在慕课网上学习剑指Java面试-Offer直通车时所做的笔记. 目录 第一章 基本概念 1.1 Fork/Join框架 1.2 为什么要使用线程池 第二章 源码理解 2.1 J.U.C的三个Executor接口 第三章 线程池的设计与实现 3.1 线程池的构造函数 3.2 线程池的执行步骤 3.3 线程池的状态 3.4 生命周期与线程池大小选定 第一章 基本概念 ...

仰望星空 387
上一篇: 画图解释 SQL join 语句
下一篇: Spring MVC实际项目中的应用
ImagineDranges
博客等级 码龄9年 4粉丝 15原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值