并发编程入门

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

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

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

看起来并发也没有多大的作用噢!平常的编程工作并没有遇到很多的阻塞问题,或者涉及到并发问题。就拿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了。

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

相关文章
|
6天前
|
人工智能 安全 Linux
【OpenClaw保姆级图文教程】阿里云/本地部署集成模型Ollama/Qwen3.5/百炼 API 步骤流程及避坑指南
2026年,AI代理工具的部署逻辑已从“单一云端依赖”转向“云端+本地双轨模式”。OpenClaw(曾用名Clawdbot)作为开源AI代理框架,既支持对接阿里云百炼等云端免费API,也能通过Ollama部署本地大模型,完美解决两类核心需求:一是担心云端API泄露核心数据的隐私安全诉求;二是频繁调用导致token消耗过高的成本控制需求。
4765 7
|
14天前
|
人工智能 JavaScript Ubuntu
5分钟上手龙虾AI!OpenClaw部署(阿里云+本地)+ 免费多模型配置保姆级教程(MiniMax、Claude、阿里云百炼)
OpenClaw(昵称“龙虾AI”)作为2026年热门的开源个人AI助手,由PSPDFKit创始人Peter Steinberger开发,核心优势在于“真正执行任务”——不仅能聊天互动,还能自动处理邮件、管理日程、订机票、写代码等,且所有数据本地处理,隐私完全可控。它支持接入MiniMax、Claude、GPT等多类大模型,兼容微信、Telegram、飞书等主流聊天工具,搭配100+可扩展技能,成为兼顾实用性与隐私性的AI工具首选。
20555 112
|
10天前
|
人工智能 API 网络安全
Mac mini × OpenClaw 保姆级配置教程(附阿里云/本地部署OpenClaw配置百炼API图文指南)
Mac mini凭借小巧机身、低功耗和稳定性能,成为OpenClaw(原Clawdbot)本地部署的首选设备——既能作为家用AI节点实现7×24小时运行,又能通过本地存储保障数据隐私,搭配阿里云部署方案,可灵活满足“长期值守”与“隐私优先”的双重需求。对新手而言,无需复杂命令行操作,无需专业技术储备,按本文步骤复制粘贴代码,即可完成OpenClaw的全流程配置,同时接入阿里云百炼API,解锁更强的AI任务执行能力。
6538 2
|
11天前
|
人工智能 安全 前端开发
Team 版 OpenClaw:HiClaw 开源,5 分钟完成本地安装
HiClaw 基于 OpenClaw、Higress AI Gateway、Element IM 客户端+Tuwunel IM 服务器(均基于 Matrix 实时通信协议)、MinIO 共享文件系统打造。
7907 6
|
12天前
|
人工智能 JavaScript API
保姆级教程:OpenClaw阿里云/本地部署配置Tavily Search skill 实时联网,让OpenClaw“睁眼看世界”
默认状态下的OpenClaw如同“闭门造车”的隐士,仅能依赖模型训练数据回答问题,无法获取实时新闻、最新数据或训练截止日期后的新信息。2026年,激活其联网能力的最优方案是配置Tavily Search技能——无需科学上网、无需信用卡验证,每月1000次免费搜索额度完全满足个人需求,搭配ClawHub技能市场,还能一键拓展天气查询、邮件管理等实用功能。
7575 5
|
6天前
|
JavaScript Linux API
保姆级教程,通过GACCode在国内使用Claudecode、Codex!
保姆级教程,通过GACCode在国内使用Claudecode、Codex!
3411 1
保姆级教程,通过GACCode在国内使用Claudecode、Codex!

热门文章

最新文章