首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【旧】G003Spring学习笔记-IOC之注解方式实现

【旧】G003Spring学习笔记-IOC之注解方式实现

作者头像
訾博ZiBo
发布于 2025-01-06 07:08:38
发布于 2025-01-06 07:08:38
8600
代码可运行
举报
运行总次数:0
代码可运行

重点知识点总结:

2020年3月18日14:19:13

1、曾经的XML配置方式

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<bean id="accountService" class="com.zibo.services.impl.IAccountServiceImpl"
  scope="" init-method="" destroy-method="">
    <property name="" value="" / ref=""/>
</bean>

2、注解的分类

用于创建对象的注解:

它们和在xml中编写<bean/>标签实现的功能是一样的;

Component:用于把当前类作为存入spring容器中;

属性:value用于指定bean的id,当我们不写时,默认为当前类名,首字母小写;

Controller:一般用在表现层;

Service:一般用在业务层;

Repository:一般用在持久层;

上面三个注解跟Component的作用是一模一样的,它们三个是spring框架为三层提供的明确注解,使三层对象看起来更清晰;

用于注入数据的注解:

它们和在xml中的<bean/>标签中写一个<property/>的作用是一样的;

用于改变作用范围的注解:

它们和在xml中使用scope属性实现的功能是一样的;

和生命周期有关的注解:

它们和在xml中使用init-method和destroy-method属性实现的功能是一样的;

一、注解方式说明及入门示例

1、说明

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 * 账户的业务层实现类
 * 曾经的xml配置:
 * <bean id="accountService" class="com.zibo.services.impl.IAccountServiceImpl"
 * scope="" init-method="" destroy-method="">
 *   <property name="" value="" / ref=""/>
 * </bean>
 * 用于创建对象的;它们和在xml中编写<bean/>标签实现的功能是一样的;
 * Component:用于把当前类作为存入spring容器中;
 * 属性:value用于指定bean的id,当我们不写时,默认为当前类名,首字母小写;
 * Controller:一般用在表现层;
 * Service:一般用在业务层;
 * Repository:一般用在持久层;
 * 上面三个注解跟Component的作用是一模一样的,
 * 它们三个是spring框架为三层提供的明确注解,使三层对象看起来更清晰;
 * 用于注入数据的;它们和在xml中的<bean/>标签中写一个<property/>的作用是一样的;
 * 用于改变作用范围的;它们和在xml中使用scope属性实现的功能是一样的;
 * 和生命周期相关的;它们和在xml中使用init-method和destroy-method属性实现的功能是一样的;
 */

2、入门示例

代码:

接口IAccountService:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.zibo.services;

/**
 * 业务层接口
 */
public interface IAccountService {
    /**
     * 模拟保存账户
     */
    void saveAccount();
}

接口实现类AccountServiceImpl:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.zibo.services.impl;

import com.zibo.dao.IAccountDao;
import com.zibo.dao.impl.AccountDaoImpl;
import com.zibo.services.IAccountService;
import org.springframework.stereotype.Component;

/**
 * 账户的业务层实现类
 * 曾经的xml配置:
 * <bean id="accountService" class="com.zibo.services.impl.IAccountServiceImpl"
 * scope="" init-method="" destroy-method="">
 *   <property name="" value="" / ref=""/>
 * </bean>
 * 用于创建对象的;它们和在xml中编写<bean/>标签实现的功能是一样的;
 * Component:用于把当前类作为存入spring容器中;
 * 属性:value用于指定bean的id,当我们不写时,默认为当前类名,首字母小写;
 * Controller:一般用在表现层;
 * Service:一般用在业务层;
 * Repository:一般用在持久层;
 * 上面三个注解跟Component的作用是一模一样的,
 * 它们三个是spring框架为三层提供的明确注解,使三层对象看起来更清晰;
 * 用于注入数据的;它们和在xml中的<bean/>标签中写一个<property/>的作用是一样的;
 * 用于改变作用范围的;它们和在xml中使用scope属性实现的功能是一样的;
 * 和生命周期相关的;它们和在xml中使用init-method和destroy-method属性实现的功能是一样的;
 */
@Component(value = "accountService")//如果注解中只有一个value,value是乐意省略的
public class AccountServiceImpl implements IAccountService {
    private IAccountDao iAccountDao = new AccountDaoImpl();
    @Override
    public void saveAccount() {
        iAccountDao.saveAccount();
    }
}

Client类:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.zibo.ui;

import com.zibo.services.IAccountService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * 模拟表现层,调用业务层
 */
public class Client {
    public static void main(String[] args) {
        /*
         * 获取spring的IOC的核心容器,并根据id获取对象
         * ApplicationContext的三个常用实现类:
         * 1、ClassPathXmlApplicationContext(xml方式最常用):仅能加载类路径下的配置文件;
         * 2、FileSystemApplicationContext:可以加载磁盘任意路径下的配置文件(必须有访问权限);
         * 3、AnnotationConfigApplicationContext:用于读取注解创建容器;
         */
        //1、获取核心容器对象
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        //2、根据id获取bean对象
        IAccountService service = ac.getBean("accountService",IAccountService.class);
        System.out.println(service);
    }
}

bean.xml:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">
        <!--告诉spring要创建容器时要扫描的包,但是配置所需要的标签不在<beans/>标签中,
        而是一个名称为context的名称空间和约束中-->
    <context:component-scan base-package="com.zibo"/>
</beans>

pom.xml:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>spring04</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
    </dependencies>

</project>

文件位置图:

运行结果:

二、深入注解方式

1、自动按照类型注入

说明:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 * 用于注入数据的;它们和在xml中的<bean/>标签中写一个<property/>的作用是一样的;
 * Autowired:
 *  作用:自动按照类型注入,只要容器中有唯一的一个bean对象类型和要注入的变量类型匹配,就可以注入成功;
 *      补充:
 *          如果没有则注入失败;
 *          如果有多个则在按照类型匹配之后再按照key匹配,匹配到与变量名相同的bean则成功;
 *  出现位置:成员变量上、方法上;
 *  细节:在使用注解时,set方法就不是必须的了;
代码示例:

(部分代码,其他代码见上面)

接口IAccountDao:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.zibo.dao;

public interface IAccountDao {
    void saveAccount();
}

接口实现类AccountDaoImpl:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.zibo.dao.impl;

import com.zibo.dao.IAccountDao;
import org.springframework.stereotype.Component;

@Component("accountDao")
public class AccountDaoImpl implements IAccountDao {
    @Override
    public void saveAccount() {
        System.out.println("保存了账户111");
    }
}

接口实现类AccountDaoImpl2:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.zibo.dao.impl;

import com.zibo.dao.IAccountDao;
import org.springframework.stereotype.Component;

@Component("accountDao2")
public class AccountDaoImpl2 implements IAccountDao {
    @Override
    public void saveAccount() {
        System.out.println("保存了账户222");
    }
}

接口实现类AccountServiceImpl:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.zibo.services.impl;

import com.zibo.dao.IAccountDao;
import com.zibo.dao.impl.AccountDaoImpl;
import com.zibo.services.IAccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

/**
 * 账户的业务层实现类
 * 曾经的xml配置:
 * <bean id="accountService" class="com.zibo.services.impl.IAccountServiceImpl"
 * scope="" init-method="" destroy-method="">
 *   <property name="" value="" / ref=""/>
 * </bean>
 * 用于创建对象的;它们和在xml中编写<bean/>标签实现的功能是一样的;
 * Component:用于把当前类作为存入spring容器中;
 *      属性:value用于指定bean的id,当我们不写时,默认为当前类名,首字母小写;
 * Controller:一般用在表现层;
 * Service:一般用在业务层;
 * Repository:一般用在持久层;
 * 上面三个注解跟Component的作用是一模一样的,
 * 它们三个是spring框架为三层提供的明确注解,使三层对象看起来更清晰;
 * 用于注入数据的;它们和在xml中的<bean/>标签中写一个<property/>的作用是一样的;
 * Autowired:
 *  作用:自动按照类型注入,只要容器中有唯一的一个bean对象类型和要注入的变量类型匹配,就可以注入成功;
 *      补充:
 *          如果没有则注入失败;
 *          如果有多个则在按照类型匹配之后再按照key匹配,匹配到与变量名相同的bean则成功;
 *  出现位置:成员变量上、方法上;
 *  细节:在使用注解时,set方法就不是必须的了;
 * 用于改变作用范围的;它们和在xml中使用scope属性实现的功能是一样的;
 * 和生命周期相关的;它们和在xml中使用init-method和destroy-method属性实现的功能是一样的;
 */
@Component("accountService")//如果注解中只有一个value,value是乐意省略的
public class AccountServiceImpl implements IAccountService {
    @Autowired//不推荐的方法
    //变量名如果是accountDao则匹配到AccountDaoImpl,如果是accountDao2则匹配到AccountDaoImpl2
    private IAccountDao accountDao2;

    @Override
    public void saveAccount() {
        accountDao2.saveAccount();
    }
}

Client类:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.zibo.ui;

import com.zibo.services.IAccountService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * 模拟表现层,调用业务层
 */
public class Client {
    public static void main(String[] args) {
        /*
         * 获取spring的IOC的核心容器,并根据id获取对象
         * ApplicationContext的三个常用实现类:
         * 1、ClassPathXmlApplicationContext(xml方式最常用):仅能加载类路径下的配置文件;
         * 2、FileSystemApplicationContext:可以加载磁盘任意路径下的配置文件(必须有访问权限);
         * 3、AnnotationConfigApplicationContext:用于读取注解创建容器;
         */
        //1、获取核心容器对象
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        //2、根据id获取bean对象
        IAccountService service = ac.getBean("accountService",IAccountService.class);
        service.saveAccount();
    }
}

文件位置图:

运行结果:

2、Qualifier

说明:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 * Qualifier:
 *  细节:在使用注解时,set方法就不是必须的了;
 *  作用:当自动类型注入出现多个匹配对象时,且变量名匹配不到相同的bean时,使用此方式;
 *  说明:它在给类成员注入时不能单独使用,在给方法注入时可单独使用;
 *  属性:value用于指定注入bean的id;
使用示例:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    @Autowired//不推荐的方法
    @Qualifier("accountDao")//指定使用accountDao,则变量名是accountDao2也必须使用accountDao
    //变量名如果是accountDao则匹配到AccountDaoImpl,如果是accountDao2则匹配到AccountDaoImpl2
    private IAccountDao accountDao2;
备注:

@Qualifier要用在@Autowired下面;

3、Resource

说明:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 * Resource:
 *  作用:直接按照bean的id注入,可以独立使用;
 *  属性:name用于指定bean的id;
使用示例:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Resource(name = "accountDao2")
注意:

不需要使用@Autowired;

在maven配置文件pom.xml中加入依赖:(???)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
        <dependency>
            <groupId>javax.annotation</groupId>
            <artifactId>javax.annotation-api</artifactId>
            <version>1.3.1</version>
        </dependency>
总结:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 * 总结:以上三个注解只能注入其他bean类型的数据,基本类型和String类型不能通过上述方法实现;
 * 另外,集合类型的注入只能通过xml实现;

4、Value

说明:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 * Value:
 *  作用:用于注入基本类型和String类型;
 *  属性:value指定数据的值,它可以使用spring中的SpEL表达式(也就是Spring的EL表达式)
 *  SpEL的写法:${表达式}

5、作用范围和生命周期的注解实现

作用范围:

说明:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 * 用于改变作用范围的;它们和在xml中使用scope属性实现的功能是一样的;
 * Scope:
 *  作用:指定Bean的作用范围;
 *  属性:value指定取值的范围,常用取值:singleton(单例,默认) prototype(多例)
 *  出现位置:类上;

代码示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Scope("prototype")//多例测试
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
        IAccountService service = ac.getBean("accountService",IAccountService.class);
        IAccountService service2 = ac.getBean("accountService",IAccountService.class);
        System.out.println(service==service2);//false
生命周期:

说明:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 * 和生命周期相关的;它们和在xml中使用init-method和destroy-method属性实现的功能是一样的;
 * PreDestroy:
 *  作用:用于指定销毁方法;
 * PostConstruct:
 *  作用:用于指定初始化方法;

代码示例:

实现类:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.zibo.services.impl;

import com.zibo.dao.IAccountDao;
import com.zibo.dao.impl.AccountDaoImpl;
import com.zibo.services.IAccountService;
import jdk.jfr.Frequency;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;

/**
 * 账户的业务层实现类
 * 曾经的xml配置:
 * <bean id="accountService" class="com.zibo.services.impl.IAccountServiceImpl"
 * scope="" init-method="" destroy-method="">
 *   <property name="" value="" / ref=""/>
 * </bean>
 * 用于创建对象的;它们和在xml中编写<bean/>标签实现的功能是一样的;
 * Component:用于把当前类作为存入spring容器中;
 *      属性:value用于指定bean的id,当我们不写时,默认为当前类名,首字母小写;
 * Controller:一般用在表现层;
 * Service:一般用在业务层;
 * Repository:一般用在持久层;
 * 上面三个注解跟Component的作用是一模一样的,
 * 它们三个是spring框架为三层提供的明确注解,使三层对象看起来更清晰;
 * 用于注入数据的;它们和在xml中的<bean/>标签中写一个<property/>的作用是一样的;
 * Autowired:
 *  作用:自动按照类型注入,只要容器中有唯一的一个bean对象类型和要注入的变量类型匹配,就可以注入成功;
 *      补充:
 *          如果没有则注入失败;
 *          如果有多个则在按照类型匹配之后再按照key匹配,匹配到与变量名相同的bean则成功;
 *  出现位置:成员变量上、方法上;
 * Qualifier:
 *  细节:在使用注解时,set方法就不是必须的了;
 *  作用:当自动类型注入出现多个匹配对象时,且变量名匹配不到相同的bean时,使用此方式;
 *  说明:它在给类成员注入时不能单独使用,在给方法注入时可单独使用;
 *  属性:value用于指定注入bean的id;
 * Resource:
 *  作用:直接按照bean的id注入,可以独立使用;
 *  属性:name用于指定bean的id;
 * 总结:以上三个注解只能注入其他bean类型的数据,基本类型和String类型不能通过上述方法实现;
 * 另外,集合类型的注入只能通过xml实现;
 * Value:
 *  作用:用于注入基本类型和String类型;
 *  属性:value指定数据的值,它可以使用spring中的SpEL表达式(也就是Spring的EL表达式)
 *  SpEL的写法:${表达式}
 * 用于改变作用范围的;它们和在xml中使用scope属性实现的功能是一样的;
 * Scope:
 *  作用:指定Bean的作用范围;
 *  属性:value指定取值的范围,常用取值:singleton(单例,默认) prototype(多例)
 *  出现位置:类上;
 * 和生命周期相关的;它们和在xml中使用init-method和destroy-method属性实现的功能是一样的;
 * FreDestroy:
 *  作用:用于指定销毁方法;
 * PostConstruct:
 *  作用:用于指定初始化方法;
 */
@Component("accountService")//如果注解中只有一个value,value是乐意省略的
//@Scope("prototype")//多例测试
public class AccountServiceImpl implements IAccountService {
//    @Autowired//不推荐的方法
//    @Qualifier("accountDao")//指定使用accountDao,则变量名是accountDao2也必须使用accountDao
    @Resource(name = "accountDao2")
    //变量名如果是accountDao则匹配到AccountDaoImpl,如果是accountDao2则匹配到AccountDaoImpl2
    private IAccountDao accountDao2;
    @PostConstruct
    private void init(){
        System.out.println("初始化。。。");
    }
    @PreDestroy
    private void destroy(){
        System.out.println("销毁。。。");
    }
    @Override
    public void saveAccount() {
        accountDao2.saveAccount();
    }
}

测试类:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.zibo.ui;

import com.zibo.services.IAccountService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * 模拟表现层,调用业务层
 */
public class Client {
    public static void main(String[] args) {
        /*
         * 获取spring的IOC的核心容器,并根据id获取对象
         * ApplicationContext的三个常用实现类:
         * 1、ClassPathXmlApplicationContext(xml方式最常用):仅能加载类路径下的配置文件;
         * 2、FileSystemApplicationContext:可以加载磁盘任意路径下的配置文件(必须有访问权限);
         * 3、AnnotationConfigApplicationContext:用于读取注解创建容器;
         */
        //1、获取核心容器对象
        ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        //2、根据id获取bean对象
        IAccountService service = ac.getBean("accountService",IAccountService.class);
        service.saveAccount();
        ac.close();
    }
}

运行结果:

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-01-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
c++中CreateEvent函数「建议收藏」
http://blog.csdn.net/chenyujing1234/article/details/8572921
全栈程序员站长
2022/09/14
1.7K0
windows 多线程_关于多线程的技术分享
本文内容较为详细,关于更简短的一篇介绍,请看这里: https://blog.csdn.net/weixin_45525272/article/details/105057120
全栈程序员站长
2022/09/23
7610
Windows编程(多线程)
CreateThread是一种微软在Windows API中提供了建立新的线程的函数,该函数在主线程的基础上创建一个新线程。线程终止运行后,线程对象仍然在系统中,必须通过CloseHandle函数来关闭该线程对象。
全栈程序员站长
2022/07/13
1.3K0
Win32线程安全问题.同步函数
  通过上面几讲.我们知道了线程怎么创建.线程切换的原理(CONTEXT结构) 每个线程在切换的时候都有自己的堆栈.
IBinary
2018/09/28
9450
Win32线程安全问题.同步函数
开启服务和停止服务
Start函数用于开启服务 1 初始化状态变量 2 创建监听套接字 3 加载使用扩展API函数 4 创建完成端口对象 5 建立监听套接字和完成端口对象间的关联 6 为监听套接字注册FD_ACCEPT时间 7 投递AcceptEx IO不够时可以得到通知后创建监听线程 BOOL CIOCOPServer::Start(int nPort,int nMaxConnnections,int nMaxFreeBuffers,int nMaxFreeContexts,int nInitialReads) {
用户1154259
2018/01/17
1.9K0
进程间通信:同步双工管道
        因为工作需要,需要设计出一个双工的IPC。(转载请指明出处)在一番比较后,我发现管道是比较符合我们的需求的。但是我们需求要求管道的对方是可信任的,而在vista以下系统是没有GetNamedPipeClientProcessId、GetNamedPipeClientSessionId、GetNamedPipeServerProcessId、
方亮
2019/01/16
1.6K0
C++ 共享内存ShellCode跨进程传输
在计算机安全领域,ShellCode是一段用于利用系统漏洞或执行特定任务的机器码。为了增加攻击的难度,研究人员经常探索新的传递ShellCode的方式。本文介绍了一种使用共享内存的方法,通过该方法,两个本地进程可以相互传递ShellCode,从而实现一种巧妙的本地传输手段。如果你问我为何在本地了还得这样传,那我只能说在某些时候我们可能会将ShellCode打散,而作为客户端也不需要时时刻刻在本地存放ShellCode代码,这能保证客户端的安全性。
王 瑞
2023/12/07
3550
打造后台登录页面扫描工具
这种工具几乎所有语言都可以完成,首选语言应该是 Python 居多,因为 Python 处理 HTTP 的库容易使用,上手更快。不过,我这里使用的是 VC 中的 MFC 来实现的。先来看看它的界面,界面如下:
码农UP2U
2021/06/10
1.9K0
【语言-C++】多线程通同步 临界区 CCriticalSection 与 CSingleLock
处理图像事件和显示图像事件同时发生时,激活图像处理线程,进行图像处理;接收图像事件的时间的触发由显示图像完成后触发;处理图像事件由相机线程图像传输来触发;
全栈程序员站长
2022/09/09
9870
老版VC++线程池
在一般的设计中,当需要一个线程时,就创建一个,但是当线程过多时可能会影响系统的整体效率,这个性能的下降主要体现在:当线程过多时在线程间来回切换需要花费时间,而频繁的创建和销毁线程也需要花费额外的机器指令,同时在某些时候极少数线程可能就可以处理大量,比如http服务器可能只需要几个线程就可以处理用户发出的http请求,毕竟相对于用户需要长时间来阅读网页来说,CPU只是找到对应位置的页面返回即可。在这种情况下为每个用户连接创建一个线程长时间等待再次处理用户请求肯定是不划算的。为了解决这种问题,提出了线程池的概念,线程池中保存一定数量的 线程,当需要时,由线程池中的某一个线程来调用对应的处理函数。通过控制线程数量从而减少了CPU的线程切换,而且用完的线程还到线程池而不是销毁,下一次再用时直接从池中取,在某种程度上减少了线程创建与销毁的消耗,从而提高效率 在Windows上,使用线程池十分简单,它将线程池做为一个整体,当需要使用池中的线程时,只需要定义对应的回调函数,然后调用API将回调函数进行提交,系统自带的线程池就会自动执行对应的回调函数。从而实现任务的执行,这种方式相对于传统的VC线程来说,程序员不再需要关注线程的创建与销毁,以及线程的调度问题,这些统一由系统完成,只需要将精力集中到逻辑处理的回调函数中来,这样将程序员从繁杂的线程控制中解放出来。同时Windows中线程池一般具有动态调整线程数量的自主行为,它会根据线程中执行任务的工作量来自动调整线程数,即不让大量线程处于闲置状态,也不会因为线程过少而有大量任务处于等待状态。 在windows上主要有四种线程池 1. 普通线程池 2. 同步对象等待线程池 3. 定时器回调线程池 4. 完成端口回调线程池
Masimaro
2018/08/31
1.6K0
互斥量Mutex的简单应用
互斥量是一个内核对象,它用来确保一个线程独占一个资源的访问。互斥量与关键段的行为非常相似,并且互斥量可以用于不同进程中的线程互斥访问资源。
全栈程序员站长
2022/09/13
4940
C语言实现简易聊天室
基于 tcp 实现群聊功能,本项目设计是在「windows环境下基于套接字(Socket)和多线程编程」进行开发的「简易聊天室」,实现了群聊功能,在VC6.0和VS2019运行测试无误。
DeROy
2020/11/19
3.6K1
C语言实现简易聊天室
CreateEvent用法
事件对象就像一个开关:它只有两种状态—开和关。当一个事件处于”开”状态,我们称其为”有信号”否则称为”无信号”。可以在一个线程的执行函数中创建一个事件对象,然后观察它的状态,如果是”无信号”就让该线程睡眠,这样该线程占用的CPU时间就比较少。
全栈程序员站长
2022/09/14
3210
C/C++ 实现多线程与线程同步
多线程中的线程同步可以使用,CreateThread,CreateMutex 互斥锁实现线程同步,通过临界区实现线程同步,Semaphore 基于信号实现线程同步,CreateEvent 事件对象的同步,以及线程函数传递单一参数与多个参数的实现方式。
王 瑞
2022/12/28
5320
C/C++ 实现多线程与线程同步
9.2 运用API实现线程同步
Windows 线程同步是指多个线程一同访问共享资源时,为了避免资源的并发访问导致数据的不一致或程序崩溃等问题,需要对线程的访问进行协同和控制,以保证程序的正确性和稳定性。Windows提供了多种线程同步机制,以适应不同的并发编程场景。主要包括以下几种:
王 瑞
2023/10/02
3790
9.2 运用API实现线程同步
临界区 互斥量 事件 信号量_互斥信号量与同步信号量
1、临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。 2、互斥量:为协调共同对一个共享资源的单独访问而设计的。 3、信号量:为控制一个具有有限数量用户资源而设计。 4、事 件:用来通知线程有一些事件已发生,从而启动后继任务的开始。
全栈程序员站长
2022/09/23
9130
Windows核心编程:第9章 用内核对象进行线程同步
https://github.com/gongluck/Windows-Core-Program.git
gongluck
2019/02/22
8630
CreateEvent方法详解
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/158198.html原文链接:https://javaforall.cn
全栈程序员站长
2022/09/14
4740
16.1 Socket 端口扫描技术
端口扫描是一种网络安全测试技术,该技术可用于确定对端主机中开放的服务,从而在渗透中实现信息搜集,其主要原理是通过发送一系列的网络请求来探测特定主机上开放的TCP/IP端口。具体来说,端口扫描程序将从指定的起始端口开始,向目标主机发送一条TCP或UDP消息(这取决于端口的协议类型)。如果目标主机正在监听该端口,则它将返回一个确认消息,这表明该端口是开放的。如果没有响应,则说明该端口是关闭的或被过滤。
王 瑞
2023/10/20
4700
16.1 Socket 端口扫描技术
Windows线程漫谈界面线程和工作者线程
每个系统都有线程,而线程的最重要的作用就是并行处理,提高软件的并发率。针对界面来说,还能提高界面的响应力。
全栈程序员站长
2022/07/15
7540
相关推荐
c++中CreateEvent函数「建议收藏」
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档