[19/04/06-星期六] 多线程_静态代理(StaticProxy)和 lamda (简化代码,jdk8新增)

本文详细介绍了静态代理的概念及其实现方式,并通过具体示例展示了如何利用静态代理进行日志记录等操作。此外,还深入探讨了Java 8中引入的Lambda表达式,解释了其在简化代码和提高编程效率方面的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、静态代理

【代码示例】

 1 /***
 2  * 静态代理:记录日志等,类是写好的,直接拿来用。 动态代理:随用随构建,临时抱佛脚
 3  * 婚庆公司:代理角色,帮你搞婚庆的一切,布置房间等等
 4  * 自己:真实角色,结婚是自己去结婚,不是婚庆公司去结婚
 5  * 
 6  * 结婚礼仪:代理相同的接口,不管谁搞流程是确定的
 7  * 
 8  */
 9 package cn.sxt.thread;
10 
11 public class Test_0406_StaticProxy {
12     public static void main(String[] args) {
13         new ProxyObject( new RealityObject() ).buy(); //代理对象里面传入一个真实的结婚对象
14         //new Thread(new Racer()).start(); 类似于这个 
15         
16     }
17     
18 }
19 //接口:结婚流程
20 interface MarryProcess{
21     void buy();//买东西
22 }
23 
24 class RealityObject implements MarryProcess{
25 
26     public void buy() { //重写buy方法
27         System.out.println("自己去采买结婚物品");
28     }
29     
30 }
31 
32 class ProxyObject implements MarryProcess{
33 
34     private MarryProcess target;//代理谁,就是放一个真实角色
35     
36     
37     public ProxyObject(MarryProcess target) {
38         super();
39         this.target = target;        
40     }
41 
42     public void buy() {//重写buy方法
43         ready();//这里可以写登录日志呀等等
44         this.target.buy(); //this.target指的是真实的角色,这里的buy()是接口中的buy()方法
45         after();//这里可以用作释放资源呀
46     }
47     private void ready() {
48         System.out.println("买烟酒");
49         
50     }
51     private void after() {
52         System.out.println("收拾桌子");
53         
54     }
55     
56 }

二、lamda表达式

 

/**jdk8新增
 * lambda表达式 
 * 1、避免匿名内部类定义过多
 * 2、实质属于函数式编程
 * 3、简化线程(一般是只用一次的线程)的使用
 * 
 */
package cn.sxt.thread;


public class Test_0406_Lambda {
    //知识点1:类放在类中,静态内部类Test01,不使用它,编译器不会编译
    static class Test01 implements Runnable{
        //线程入口入口点
        public void run() {
            for (int i = 0; i <5; i++) {
                System.out.println("爱你呦!");
            }            
        }    
    } 

    public static void main(String[] args) {//主方法,代码从这里开始
        //new Thread(new Test01()).start(); //new Test01()类仅用一次


        //知识点2:类放在方法里边 称之为局部内部类
        class Test02 implements Runnable{
            //线程入口入口点
            public void run() {
                for (int i = 0; i <5; i++) {
                    System.out.println("爱你一万年!");
                }            
            }    
        } 

        new Thread(new Test02()).start();//new Test02()类仅用一次


        //知识点3、匿名内部类,必须借助接口或者父类。与上边相比没有一个具体的类名
        new Thread(new Runnable(){ //Runnable()是个接口不可示例化,所以加上{。。。},里边是类体,且重写run()方法
            public void run() {
                for (int i = 0; i<5; i++) {
                    System.out.println("love you ");
                }            
            }                

        } ).start();


        //知识点4、lambda表达式,由上边3点演化过来,省去了new Runnable(){public void run()
        //}和更加简化 ,仅限于里边有一个方法,本机安装的版本是jdk1.7的,不支持
/*
        new Thread( ()-> {
            for (int i = 0; i<5; i++) {
                System.out.println("喜欢你 ");
            }            
        } ).start();*/
    }
}

 

转载于:https://www.cnblogs.com/ID-qingxin/p/10668213.html

vae@vae-ASUS-TUF-Gaming-A15-FA507UU-FA507UU:~/primitive_ws/src/Primitive-Planner/src/scripts$ roslaunch primitive_planner swarm.launch ... logging to /home/vae/.ros/log/bd228878-6248-11f0-9b88-51c660762ec6/roslaunch-vae-ASUS-TUF-Gaming-A15-FA507UU-FA507UU-36532.log Checking log directory for disk usage. This may take a while. Press Ctrl-C to interrupt Done checking log file disk usage. Usage is <1GB. started roslaunch server http://vae-ASUS-TUF-Gaming-A15-FA507UU-FA507UU:40573/ SUMMARY ======== PARAMETERS * /drone_0_bridge_node/broadcast_ip: 127.0.0.255 * /drone_0_bridge_node/drone_id: 0 * /drone_0_bridge_node/odom_max_freq: 70 * /drone_0_odom_visualization/color/a: 1.0 * /drone_0_odom_visualization/color/b: 0.0 * /drone_0_odom_visualization/color/g: 0.0 * /drone_0_odom_visualization/color/r: 0.0 * /drone_0_odom_visualization/covariance_scale: 100.0 * /drone_0_odom_visualization/drone_id: 0 * /drone_0_odom_visualization/robot_scale: 0.24 * /drone_0_odom_visualization/tf45: False * /drone_0_pcl_render_node/cam_cx: 321.04638671875 * /drone_0_pcl_render_node/cam_cy: 243.44969177246094 * /drone_0_pcl_render_node/cam_fx: 387.229248046875 * /drone_0_pcl_render_node/cam_fy: 387.229248046875 * /drone_0_pcl_render_node/cam_height: 480 * /drone_0_pcl_render_node/cam_width: 640 * /drone_0_pcl_render_node/estimation_rate: 30.0 * /drone_0_pcl_render_node/map/x_size: 20.63661977236758 * /drone_0_pcl_render_node/map/y_size: 20.63661977236758 * /drone_0_pcl_render_node/map/z_size: 3.0 * /drone_0_pcl_render_node/sensing_horizon: 5.0 * /drone_0_pcl_render_node/sensing_rate: 10.0 * /drone_0_poscmd_2_odom/init_x: 0.3183098861837907 * /drone_0_poscmd_2_odom/init_y: 0.0 * /drone_0_poscmd_2_odom/init_z: 0.5 * /drone_0_primitive_planner_node/fsm/fail_safe: True * /drone_0_primitive_planner_node/fsm/flight_type: 2 * /drone_0_primitive_planner_node/fsm/no_replan_thresh: 0.5 * /drone_0_primitive_planner_node/fsm/realworld_experiment: True * /drone_0_primitive_planner_node/fsm/thresh_replan_time: 0.2 * /drone_0_primitive_planner_node/fsm/waypoint0_x: -0.3183098861837907 * /drone_0_primitive_planner_node/fsm/waypoint0_y: -0.0 * /drone_0_primitive_planner_node/fsm/waypoint0_z: 0.5 * /drone_0_primitive_planner_node/fsm/waypoint1_x: 0.0 * /drone_0_primitive_planner_node/fsm/waypoint1_y: 0.0 * /drone_0_primitive_planner_node/fsm/waypoint1_z: 0.0 * /drone_0_primitive_planner_node/fsm/waypoint2_x: 0.0 * /drone_0_primitive_planner_node/fsm/waypoint2_y: 0.0 * /drone_0_primitive_planner_node/fsm/waypoint2_z: 0.0 * /drone_0_primitive_planner_node/fsm/waypoint_num: 1 * /drone_0_primitive_planner_node/manager/arc_length: 3.0 * /drone_0_primitive_planner_node/manager/boxX: 6.0 * /drone_0_primitive_planner_node/manager/boxY: 6.0 * /drone_0_primitive_planner_node/manager/boxZ: 6.0 * /drone_0_primitive_planner_node/manager/depthCloudStackNum: 1 * /drone_0_primitive_planner_node/manager/drone_id: 0 * /drone_0_primitive_planner_node/manager/lamda_b: 50.0 * /drone_0_primitive_planner_node/manager/lamda_l: 200.0 * /drone_0_primitive_planner_node/manager/map_size_x: 20.63661977236758 * /drone_0_primitive_planner_node/manager/map_size_y: 20.63661977236758 * /drone_0_primitive_planner_node/manager/map_size_z: 3.0 * /drone_0_primitive_planner_node/manager/max_vel: 1.0 * /drone_0_primitive_planner_node/manager/primitiveFolder: /home/vae/primiti... * /drone_0_primitive_planner_node/manager/sampleSize: 10000 * /drone_0_primitive_planner_node/manager/swarm_clearence: 0.24 * /drone_0_primitive_planner_node/manager/voxelSize: 0.1 * /drone_0_traj_server/init_x: 0.3183098861837907 * /drone_0_traj_server/init_y: 0.0 * /drone_0_traj_server/init_z: 0.5 * /drone_0_traj_server/traj_server/max_vel: 1.0 * /drone_0_traj_server/traj_server/primitiveFolder: /home/vae/primiti... * /drone_0_traj_server/traj_server/time_delay_idx: 0 * /drone_0_traj_server/traj_server/time_forward: 1.0 * /random_forest/ObstacleShape/lower_hei: 0.0 * /random_forest/ObstacleShape/lower_rad: 0.2 * /random_forest/ObstacleShape/radius_h: 0.5 * /random_forest/ObstacleShape/radius_l: 0.7 * /random_forest/ObstacleShape/theta: 0.5 * /random_forest/ObstacleShape/upper_hei: 3.0 * /random_forest/ObstacleShape/upper_rad: 0.5 * /random_forest/ObstacleShape/z_h: 0.8 * /random_forest/ObstacleShape/z_l: 0.7 * /random_forest/map/circle_num: 0.46484179349639226 * /random_forest/map/obs_num: 0.46484179349639226 * /random_forest/map/resolution: 0.1 * /random_forest/map/x_size: -0.9642010096410315 * /random_forest/map/y_size: -0.9642010096410315 * /random_forest/map/z_size: 3.0 * /random_forest/min_distance: 0.8 * /random_forest/pub_rate: 1.0 * /rosdistro: noetic * /rosversion: 1.17.4 NODES / drone_0_bridge_node (swarm_bridge/bridge_node_udp) drone_0_odom_visualization (odom_visualization/odom_visualization) drone_0_pcl_render_node (local_sensing_node/pcl_render_node) drone_0_poscmd_2_odom (poscmd_2_odom/poscmd_2_odom) drone_0_primitive_planner_node (primitive_planner/primitive_planner_node) drone_0_traj_server (primitive_planner/traj_server) random_forest (map_generator/random_forest) rviz (rviz/rviz) auto-starting new master process[master]: started with pid [36557] ROS_MASTER_URI=http://localhost:11311 setting /run_id to bd228878-6248-11f0-9b88-51c660762ec6 process[rosout-1]: started with pid [36582] started core service [/rosout] process[drone_0_bridge_node-2]: started with pid [36589] process[random_forest-3]: started with pid [36590] process[rviz-4]: started with pid [36591] process[drone_0_primitive_planner_node-5]: started with pid [36597] process[drone_0_traj_server-6]: started with pid [36599] process[drone_0_poscmd_2_odom-7]: started with pid [36600] process[drone_0_odom_visualization-8]: started with pid [36601] process[drone_0_pcl_render_node-9]: started with pid [36611] [ERROR] [1752672500.302585947]: Illegal pathID=-1 [rosmsg_tcp_bridge] start running [drone_0_primitive_planner_node-5] process has finished cleanly log file: /home/vae/.ros/log/bd228878-6248-11f0-9b88-51c660762ec6/drone_0_primitive_planner_node-5*.log [WARN] [1752672500.791081325]: Finished generate random map [pcl::KdTreeFLANN::setInputCloud] Cannot create a KDTree with an empty input cloud! [WARN] [1752672500.794334498]: Global Pointcloud received.. [pcl::KdTreeFLANN::setInputCloud] Cannot create a KDTree with an empty input cloud! [drone_0_pcl_render_node-9] process has died [pid 36611, exit code -11, cmd /home/vae/primitive_ws/devel/lib/local_sensing_node/pcl_render_node ~global_map:=/map_generator/global_cloud ~odometry:=/drone_0_visual_slam/odom ~pcl_render_node/cloud:=/drone_0_pcl_render_node/cloud __name:=drone_0_pcl_render_node __log:=/home/vae/.ros/log/bd228878-6248-11f0-9b88-51c660762ec6/drone_0_pcl_render_node-9.log]. log file: /home/vae/.ros/log/bd228878-6248-11f0-9b88-51c660762ec6/drone_0_pcl_render_node-9*.log [INFO] [1752672501.293613925]: [Traj server]: ready. [rospack] Error: failed to parse command-line options: too many positional options have been specified on the command line [librospack]: error while executing command [rospack] Error: failed to parse command-line options: too many positional options have been specified on the command line [librospack]: error while executing command [rospack] Error: failed to parse command-line options: too many positional options have been specified on the command line [librospack]: error while executing command [WARN] [1752672547.878321128]: Shutdown request received. [WARN] [1752672547.878370290]: Reason given for shutdown: [user request] [random_forest-3] process has finished cleanly log file: /home/vae/.ros/log/bd228878-6248-11f0-9b88-51c660762ec6/random_forest-3*.log
07-17
<think>我们面对的问题有两个错误信息:1. Illegal pathID=-1;2. pcl::KdTreeFLANN::setInputCloud错误(即尝试用空点云创建KDTree)。根据引用[4]中的经验,第二个错误通常与点云数据为空有关。而第一个错误“Illegal pathID=-1”可能与路径规划或地图数据有关。下面我们逐步分析: ### 错误1: Illegal pathID=-1 这个错误通常出现在导航栈(navigation stack)中,尤其是在使用全局规划器(global planner)时。`pathID`是路径的标识符,当值为-1时表示无效路径。可能原因包括: - 全局规划器未能生成有效路径(例如,起点或终点设置在障碍物上,或者地图数据异常) - 规划器参数配置不当 ### 错误2: pcl::KdTreeFLANN::setInputCloud 这个错误明确表示尝试为一个空的点云创建KDTree。KDTree是用于高效近邻搜索的数据结构,要求输入点云非空。可能原因包括: - 点云话题未发布数据(可能是传感器未发布,或者话题名称不匹配) - 点云数据在传输或转换过程中丢失(例如,在ROS消息到PCL点云转换时出现异常) ### 解决步骤 #### 1. 检查点云话题 根据引用[4]的经验,点云话题名称不匹配是常见原因。请确保: - 你的启动文件中订阅的点云话题名称与实际发布的话题名称一致。 - 使用`rostopic list`查看当前发布的话题,确认点云话题(如`/velodyne_points`)存在。 - 使用`rostopic echo /velodyne_points | head`查看点云数据是否正常。 如果话题名称不一致,修改启动文件或节点代码中的话题名称。例如,引用[4]中提到,将`utility.h`文件中的激光点云话题名称改为`/velodyne_points`。 #### 2. 检查点云数据流 如果话题名称正确,但点云仍为空,需检查点云数据流: - 确保传感器驱动程序正常运行,发布点云数据。 - 检查是否有节点在点云话题上进行了过滤,导致输出为空。 #### 3. 检查点云转换代码 如果使用了自定义节点进行点云处理,参考引用[2][3]中的转换代码,确保从ROS消息到PCL点云的转换正确。例如,引用[3]中的代码展示了如何将`sensor_msgs::PointCloud2`转换为`pcl::PointCloud<pcl::PointXYZ>`,并检查是否为空: ```cpp void Motion::Laser::connectMsg(const sensor_msgs::PointCloud2ConstPtr &ptrMsg) { // ... 转换代码 if (ptrCloud->empty()) { // 处理空点云情况 } } ``` 确保在转换后检查点云是否为空,并处理空点云情况。 #### 4. 检查全局规划器配置 对于“Illegal pathID=-1”错误,请检查: - 全局规划器参数(如`base_global_planner`)设置是否正确。 - 起点终点是否在代价地图的可通行区域内(使用RViz检查)。 - 代价地图是否正常更新(无异常障碍物)。 #### 5. 运行诊断工具 - 使用`rviz`可视化点云地图,确认数据是否正常。 - 使用`rosnode info <node_name>`查看节点订阅发布的话题,确认连接关系。 ### 示例解决方案 假设错误是由于点云话题名称不匹配引起,修改步骤如下(以引用[4]为例): 1. 找到定义点云话题名称的文件(如`utility.h`)。 2. 将点云话题名称改为实际发布的话题(如`/velodyne_points`)。 3. 重新编译运行:`catkin_make`,然后重新启动。 如果问题仍未解决,请提供更多上下文信息(如启动文件内容、节点代码片段等),以便进一步分析。 §§相关问题§§ 1. ROS中如何查看当前发布的所有话题? 2. 如何调试ROS节点中的点云处理代码? 3. 全局规划器常见错误有哪些?</think>### ROS Launch文件错误排查 针对您遇到的`Illegal pathID=-1``pcl::KdTreeFLANN::setInputCloud`错误,以下是系统性排查方案: --- ### **错误1:`Illegal pathID=-1`** #### 可能原因 1. **路径规划参数错误**:全局/局部规划器配置异常(如无效目标点) 2. **地图数据缺失**:导航栈未加载有效地图(如空地图或坐标系错误) 3. **TF变换异常**:机器人坐标系(如`base_link`)与地图坐标系(如`map`)未正确关联 #### 解决步骤: 1. **检查TF树**: ```bash rosrun tf view_frames # 生成TF树PDF evince frames.pdf # 查看坐标系连接 ``` 确保`map`→`odom`→`base_link`链路完整[^4]。 2. **验证目标点有效性**: ```bash rostopic echo /move_base/goal # 检查目标点数据 ``` 确保目标点在代价地图的可通行区域内。 3. **重置导航栈**: ```bash rosservice call /move_base/clear_costmaps ``` --- ### **错误2:`pcl::KdTreeFLANN::setInputCloud`** #### 关键原因(引用[4]经验) > **空点云输入**:KDTree要求非空点云,但算法收到空点云数据 #### 解决流程: 1. **确认点云话题数据流**: ```bash rostopic list | grep point_cloud # 查找实际发布的话题 rostopic hz /velodyne_points # 检查数据频率(确保>1Hz) rostopic echo /velodyne_points | head -n 1 # 查看消息结构 ``` 2. **修正话题名称匹配**(引用[4]方案): - 编辑`utility.h`文件: ```cpp // 确保与bag文件发布的话题一致 const std::string POINT_CLOUD_TOPIC = "/velodyne_points"; ``` - 重新编译: ```bash catkin_make clean && catkin_make ``` 3. **检查点云转换代码**(引用[2][3]): ```cpp pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>); pcl::fromROSMsg(*input_msg, *cloud); // ROS消息转PCL格式 // 必须添加空点云检查! if (cloud->empty()) { ROS_ERROR("Received empty point cloud!"); return; } kdtree.setInputCloud(cloud); // 确保此处cloud非空 ``` 4. **传感器驱动验证**: - 单独运行传感器驱动节点: ```bash roslaunch velodyne_pointcloud VLP16_points.launch ``` - 使用`rviz`可视化点云: ```bash rviz -d $(rospack find velodyne_pointcloud)/launch/velodyne.rviz ``` --- ### **综合调试建议** 1. **逐步启动法**: ```bash roslaunch --screen your_pkg launch_file.launch # 显示所有节点输出 ``` 观察报错节点的完整堆栈信息。 2. **检查依赖项**: ```bash rospack depends1 your_pkg # 检查包依赖 rosdep check your_pkg # 验证依赖安装 ``` 3. **数据集兼容性**: - 确认使用的bag文件与传感器配置匹配(如VLP-16 vs Ouster) ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值