并发编程入门

简介: 并发编程一直是一个令人困惑的问题,主要的原因在于:使用并发时需要解决的问题会有很多;另外实现并发的方式不止一种,实现方式的选择也是一大问题。谈到并发,首先稍微介绍下什么是并发,相信很多人都已经对这个概念比较熟悉,并发编程是相对顺序编程的一种新的模式。

并发编程一直是一个令人困惑的问题,主要的原因在于:使用并发时需要解决的问题会有很多;另外实现并发的方式不止一种,实现方式的选择也是一大问题。

谈到并发,首先稍微介绍下什么是并发,相信很多人都已经对这个概念比较熟悉,并发编程是相对顺序编程的一种新的模式。它可以一定程度的提高程序的执行速度。主要针对程序的阻塞性,因为程序的阻塞使得程序运行效率降低,而并发在一定程度上解决了程序的阻塞性带来的运行效率问题。所以也可以说,从性能的角度看,如果没有任务会阻塞,那么单处理器上的并发就没有了意义。

看起来并发也没有多大的作用噢!平常的编程工作并没有遇到很多的阻塞问题,或者涉及到并发问题。就拿Java语言来说。其实不然,Servlet对于熟悉Java的人来说再熟悉不过,而这个作为Web系统最基础的一个类天生就具有多线程性,而对并发的熟悉能使得我们充分利用这些处理器。

并发编程使得我们可以将程序划分为多个分离的、独立运行的任务,通过多线程机制,这些独立任务中的每一个都将由执行线程来驱动。一个线程就是在进程中的一个单一的顺序控制流,因此,单个进程可以拥有多个并发执行的任务,但程序使得每个任务都好像有其自己的CPU一样。其底层机制是切分CPU时间片,这些通常不需要考虑。[p653]

了解了并发相关的一些概念,接下来学习学习Java中的并发编程。

Java中Runnable代表一个任务,要实现线程行为,需要显式地将这个任务附着到线程(Thread)上,

public class BasicThreads{
    public static void main (String args[]){
        Thread t = new Thread(new LiftOff());   //LiftOff是一个任务
        t.start();
    }
}

从任务中产生返回值

Runnable是执行工作的独立任务,他不返回任何值。如果希望在任务完成时能够返回一个值,那么可以实现Callable接口而不是Runnable接口。
如何使用Callable呢?
首先Callable是一种具有类型参数的泛型,它的类型参数表示的是从方法call()中返回的值;并且必须使用ExecutorService.submit()方法调用它,示例:

public class CallableDemo {
    public static void main(String args[]){
        ExecutorService exec = Executors.newCachedThreadPool();
        ArrayList<Future<String>> results = new ArrayList<Future<String>>();
        for (int i = 0; i < 10; i++) {
            results.add(exec.submit(new TaskwithResult(i)));
        }
        for(Future<String> fs : results){
            try {
                System.out.println(fs.get());
            }catch(Exception e){
                System.out.println(e);
            }finally {
                exec.shutdown();
            }
        }
    }
}

class TaskwithResult implements Callable<String>{
    private int id ;
    public TaskwithResult(int id){
        this.id = id ;
    }
    public String call(){
        return "result of TaskWithResult " + id ;
    }
}

submit()方法会产生Future对象,它用Callable返回结果的特定类型进行了参数化,可以用isDone()方法来查询Future是否已经完成。[p659]

优先级

线程的优先级,优先级较低的只是执行的频率比较低,并不是优先级低的将不会在优先级高的线程前执行(即,优先级不会导致死锁)。
在绝大多数时间,线程的优先级都应该以默认优先级运行,试图操作线程优先级通常是一种错误。

读取线程优先级

getPriority();

修改优先级

setPriority();

让步

yield();

给线程调度机制一个暗示:工作已经差不多了,可以让别的线程使用CPU了。

但是这个暗示没有任何机制保证它会被采纳。当调用这个方法时,只是在建议具有相同优先级的其他线程可以运行。

相关文章
|
2天前
|
数据采集 人工智能 安全
|
11天前
|
云安全 监控 安全
|
3天前
|
自然语言处理 API
万相 Wan2.6 全新升级发布!人人都能当导演的时代来了
通义万相2.6全新升级,支持文生图、图生视频、文生视频,打造电影级创作体验。智能分镜、角色扮演、音画同步,让创意一键成片,大众也能轻松制作高质量短视频。
1021 151
|
3天前
|
编解码 人工智能 机器人
通义万相2.6,模型使用指南
智能分镜 | 多镜头叙事 | 支持15秒视频生成 | 高品质声音生成 | 多人稳定对话
|
17天前
|
机器学习/深度学习 人工智能 自然语言处理
Z-Image:冲击体验上限的下一代图像生成模型
通义实验室推出全新文生图模型Z-Image,以6B参数实现“快、稳、轻、准”突破。Turbo版本仅需8步亚秒级生成,支持16GB显存设备,中英双语理解与文字渲染尤为出色,真实感和美学表现媲美国际顶尖模型,被誉为“最值得关注的开源生图模型之一”。
1719 9
|
8天前
|
人工智能 自然语言处理 API
一句话生成拓扑图!AI+Draw.io 封神开源组合,工具让你的效率爆炸
一句话生成拓扑图!next-ai-draw-io 结合 AI 与 Draw.io,通过自然语言秒出架构图,支持私有部署、免费大模型接口,彻底解放生产力,绘图效率直接爆炸。
660 152
|
10天前
|
人工智能 安全 前端开发
AgentScope Java v1.0 发布,让 Java 开发者轻松构建企业级 Agentic 应用
AgentScope 重磅发布 Java 版本,拥抱企业开发主流技术栈。
625 13
|
5天前
|
SQL 自然语言处理 调度
Agent Skills 的一次工程实践
**本文采用 Agent Skills 实现整体智能体**,开发框架采用 AgentScope,模型使用 **qwen3-max**。Agent Skills 是 Anthropic 新推出的一种有别于mcp server的一种开发方式,用于为 AI **引入可共享的专业技能**。经验封装到**可发现、可复用的能力单元**中,每个技能以文件夹形式存在,包含特定任务的指导性说明(SKILL.md 文件)、脚本代码和资源等 。大模型可以根据需要动态加载这些技能,从而扩展自身的功能。目前不少国内外的一些框架也开始支持此种的开发方式,详细介绍如下。
383 4