精华内容
下载资源
问答
  • 线程的实现和使用场景

    万次阅读 2021-06-09 22:06:20
    线程的实现和使用场景一、线程实现方式1.1 Thread实现1.2 Runnable实现二、线程的使用场景1.线程使用场景1.1 线程应该最多的场景:1.2线程的常见应用场景:2.线程小案列2.1 线程计算2.2 线程实现...

    一、多线程实现方式

    1.1 Thread实现

    继承Thread类并重写它的run方法。之后创建这个子类的对象并调用start()方法。下面直接上代码:

    /**
    *描述
    * @author cy
    * @date 2021-06-09
    * @return
    **/
    public class TreadTest  extends  Thread{
        public static void main(String[] args) {
            //创建两个线程
            TreadTest thread1 = new TreadTest();
            TreadTest thread2 = new TreadTest();
            thread1.start();
            thread2.start();
        }
        @Override
        public void run() {
           for (int i = 0;i < 100;i++){
               //分别打印线程名称和i
               System.out.println("threadName:"
               +Thread.currentThread()+";i="+i);
           }
        }
    }
    

    输出结果可以看到两个线程交替打印。线程启动成功。
    在这里插入图片描述

    1.2 Runnable实现

    Runnable的实现方式是实现其接口,下面请看具体的实现代码

    
    /**
     * @author  cy
     * @date  2021-06-09
     *@deprecated  Runnable实现多线程
     */
    public class RunnableDemoTest {
    
        public static void main(String[] args) {
            //新建两个线程
            RunnableDemoTest1 r =  
            new RunnableDemoTest1();
            new Thread(r).start();
            new  Thread(r).start();
        }
    
        /**
         * 通过runnable 方式实现多线程
          */
    static class  RunnableDemoTest1  
                       implements  Runnable{
        @Override
        public void run() {
            for (int i = 0 ;i < 5 ;i++)
                System.out.println("threadName:"
                +Thread.currentThread()+";i="+i);
        }
    }
    }
    
    

    从输出结果中我们可以看到两个线程交替打印。线程启动成功。
    在这里插入图片描述

    二、多线程的使用场景

    1.多线程使用场景

    1.1 多线程应该最多的场景:

    web服务器本身; 各种专用服务器(如游戏服务器);

    1.2多线程的常见应用场景:

    1、后台任务,例如:定时向大量(100w以上)的用户发送邮件; 2、异步处理,例如:发微博、记录日志等; 3、分布式计算

    2.多线程小案列

    2.1 多线程计算

    计算一亿个数字之和,在没有学习多线程之前,也是可以实现的,我们可以通过循环一亿次进行累加,最后得出结果。
    代码如下:

    package trhead;
    
    import java.util.Random;
    
    /**
     * 计算一亿个数之和
     */
    public class SumThreadDemo {
    
        private static double [] nums = new double[1_0000_0000];
        private static Random r  =  new Random();
        private static  double  result = 0.0,result1 = 0.0,result2 = 0.0;
    
        static {
            for (int i =0;i < nums.length ; i++){
                nums[i] = r.nextDouble();
            }
        }
    
        public static void main(String[] args) throws InterruptedException {
            SumThreadDemo.m1();
            SumThreadDemo.m2();
        }
    
        /**
         * 使用单线程计算
         */
        private  static  void m1(){
            long startTime = System.currentTimeMillis();
            for (int i = 0;i < nums.length;i++){
                result += nums[i];
            }
            System.out.println(result);
            long endTime = System.currentTimeMillis();
            long countTime = endTime - startTime;
            System.out.println("m1耗时:"+countTime);
        }
    
        /**
         * 使用多线程计算
         */
        private  static  void m2() throws InterruptedException {
    
    
            Thread thread1 =   new Thread(()->{
                for (int i = 0;i < nums.length/2;i++){
                    result1 += nums[i];
                }
            });
    
            Thread thread2 =   new Thread(()->{
                for (int i = nums.length/2;i < nums.length;i++){
                    result2 += nums[i];
                }
            });
            long startTime = System.currentTimeMillis();
            thread1.start();
            thread2.start();
            thread1.join();
            thread2.join();
            System.out.println(result1+ result2);
            long endTime = System.currentTimeMillis();
            long countTime = endTime - startTime;
            System.out.println("m2耗时:"+countTime);
        }
    
    
    
    }
    
    

    从输出结果中可以观察出,两个线程计算结果比单个线程快了将近两倍。如果实际应用中有这种场景,大家可以使用多线程实现。
    在这里插入图片描述

    2.2 多线程实现卖票小程序

    某电影院正在上映某大片,共5张票,而他又有3个售票窗口售票,请设计一个程序模拟该电影院售票。

    多线程实现方式1:

    package trhead;
    
    /**
    *描述
     *  某电影院正在上映某大片,共5张票,
     * 而他又有3个售票窗口售票,请设计一个程序模拟该电影院售票。
    * @author cy
    * @date 2021-06-09
    * @return
    **/
    public class TicketTreadTest extends  Thread{
        //设置票数
        private  int ticket = 5;
        public static void main(String[] args) {
            //创建两个线程
            TicketTreadTest thread1 
                  = new TicketTreadTest();
            TicketTreadTest thread2 
                  = new TicketTreadTest();
            TicketTreadTest thread3 
                  = new TicketTreadTest();
            thread1.start();
            thread2.start();
            thread3.start();
        }
        @Override
        public void run() {
            while(true){
               //分别打印线程名称 和 ticket 数
               System.out.println("threadName:"
               +Thread.currentThread()+";
               ticket="+ticket--);
               if(ticket < 0){
                   break;
                }
           }
        }
    }
    

    结果分析:从下图输出结果中可以分析,使用继承Thread类实现卖票,导致每个窗口都卖了五张票,而这个电影院总共才五张票,多线程出现了超卖现象。原因是继承Thread方式,是多线程多实例,无法实现资源的共享
    在这里插入图片描述

    2.3多线程卖票小程序优化

    在2.2的小程序案列中,我们发现了在多线程的环境下, 由于公共资源可能会被多个线程共享, 也就是多个线程可能会操作同一资源. 当多个线程操作同一块资源时, 很容易导致数据错乱或发生数据安全问题,
    即: 数据有可能丢失, 有可能增加, 有可能错乱.

    我们如何避免这种现象呢?具体看代码:

    package trhead;
    
    /**
     * @author  cy
     * @date  2021-06-09
     *@deprecated  Runnable实现多线程卖票
     */
    public class TicketRunnableDemoTest {
        //设置票数
        private  static int ticket = 5;
    
        public static void main(String[] args) {
            //新建两个线程
            RunnableDemoTest1 r 
                   =  new RunnableDemoTest1();
            new Thread(r).start();
            new  Thread(r).start();
        }
    
        /**
         * 通过runnable 方式实现多线程
          */
    static class  RunnableDemoTest1  
                        implements  Runnable{
        @Override
        public void run() {
            while (ticket > 0){
                saleTicket();
            }
        }
    
            /**
             * 实现卖票方法
             */
        public  void  saleTicket(){
            if(ticket>0){
                System.out.println("threadName:"
                +Thread.currentThread()
                + "正在出票,余票剩余:"+ticket-- +"张");
            }
        }
    }
    }
    
    

    结果分析:从下图输出结果中可以分析,实现Runnable接口进行卖票,电影院总共才五张票,多线程卖票正常。原因是实现Runnable方式,是多线程单实例,可实现资源的共享

    在这里插入图片描述

    2.4多线程卖票小程序优化升级

    细心的小伙伴可能会发现,怎么在2.3输出打印的票数不是从大到小排序的,这跟现实中的卖票场景不一样呐。如果想解决这样的问题,就必须使用同步,所谓的同步就是指多个操作在同一个时间段内只有一个线程进行,其他线程要等待此线程完成之后才可以继续执行
    下面我们通过对2.3代码进行继续优化,实现真实卖票场景。

     /**
    * 通过synchronized实现线程同步
      * 实现卖票方法
      */ public synchronized   void   saleTicket1(){
          if(ticket>0){
              System.out.println("threadName:"
              +Thread.currentThread()
                      + "正在出票,余票剩余:"
                      + +ticket-- +"张");
          }
      }
    

    结果分析:从下图输出结果中可以分析,通过同步代码的方法进行代码的加锁操作,实现了卖票场景。
    在这里插入图片描述


    总结

    这节主要给大家介绍了多线程的实现以及相应的一些使用场景,并且引入了同步的知识点,下一节主要介绍synchronized关键字的使用。
    另外,码字不容易,如果发现小编描述有误,麻烦指摘。

    展开全文
  • Zuul的使用场景

    万次阅读 2018-11-15 10:13:26
    Zuul的使用场景场景,今天我们就来细数一下

    Zuul Http客户端

    • Zuul使用的默认HTTP客户端现在由Apache HTTP Client支持,而不是已经不推荐使用的Ribbon RestClient
    • 要使用RestClientokhttp3.0kHttpClient,请分别设置
      ribbon.restclient.enabled = true
      //或
      ribbon.okhttp.enabled = true
      

    如果要自定义Apache HTTP客户端或OK HTTP客户端,请提供ClosableHttpClient或OkHttpClient类型的bean。

    Cookies and Sensitive Headers

    配置文件application.yml中设置

    zuul:
      routes:
        users:
          path: /myusers/**
          sensitiveHeaders: Cookie,Set-Cookie,Authorization
          url: https://downstream
    

    这里sensitiveHeaders是默认值,所以当你希望它不同时,才需进行设置。 这是Spring Cloud Netflix 1.1中的新功能(在1.0中,用户无法控制标题,并且所有Cookie都在两个方向上流动)。

    sensitiveHeaders是黑名单,且默认不为空。 因此,要使Zuul发送所有标头(忽略的标头除外),您必须将其明确设置为空列表。 如果要将cookie或授权标头传递到后端,则必须这样做。 以下示例显示了如何使用sensitiveHeaders:

    zuul:
      routes:
        users:
          path: /myusers/**
          sensitiveHeaders:
          url: https://downstream
    

    您还可以通过设置sensitiveHeaders来设置zuul.sensitiveHeaders。 如果在路由上设置了sensitiveHeaders,它将覆盖全局sensitiveHeaders设置。

    Ignored Headers

    • 常规理解:

      zuul.ignoreHeaders属性可用于丢弃一些标题。

      例如,设置zuul.ignoredHeaders = Header1,Header2;
      那么Header1和Header2将不会传播到任何其他服务。

      默认情况下,zuul.ignoredHeaders=是空的。但如果Spring Securuty在classpath中。
      它的值在是:
    Pragma,Cache-Control,X-Frame-Options,X-Content-Type-Options,X-XSS-Protextion,Expires
    

    zuul.ignoreSecurityHeaders的默认值为true。但是当我想要标头值的值时
    从下游服务我们需要设置为false。

    • 通俗来讲就是:

      route-sensitive外,您还可以将与下游服务交互期间应丢弃的值(请求和响应)设置名为zuul.ignoredHeaders的全局值。 默认情况下,如果Spring Security不在类路径中,则它们为空。 否则,它们被初始化为一组众所周知的“安全”头文件(例如,涉及缓存),如Spring Security所指定的那样。 在这种情况下的假设是下游服务也可能添加这些头,但我们想从代理中获得这些值。 如果要在Spring Security位于类路径时不丢弃这些众所周知的security headers,可以将zuul.ignoreSecurityHeaders设置为false。 如果您在Spring Security中禁用了HTTP安全响应标头并希望下游服务提供的值,那么这样做会非常有用。

    Routes Endpoint

    • 使用routes 端点的前提:
      • Zuul Server需要有Spring Boot Actuator的依赖,否则访问/routes 端点将会返回404;
      • 设置management.security.enabled = false,否则将会返回401;也可添加Spring Security的依赖,这样可通过账号、密码访问routes 端点。

    Strangulation Patterns and Local Forwards

    标题: 扼杀模式和本地转发

    迁移现有应用程序或API时的一种常见模式是“扼杀”旧端点,慢慢用不同的实现替换它们。 Zuul代理是一个有用的工具,因为您可以使用它来处理来自旧端点的客户端的所有流量,但将一些请求重定向到新的端点。

    以下示例显示“strangle”方案的配置详细信息:

    • application.yml配置示例:
    zuul:
      routes:
        first:
          path: /first/**
          url: http://first.example.com
        second:
          path: /second/**
          # forward的是本地转发
          url: forward:/second
        third:
          path: /third/**
          url: forward:/3rd
        legacy:
          path: /**
          url: http://legacy.example.com
    

    [注意] 忽略的模式不会被完全忽略,它们只是不由代理处理(因此它们也可以在本地有效转发)。

    Uploading Files through Zuul

    标题: 通过zuul上传文件

    • 如果使用@EnableZuulProxy注解,可以用代理路径上传文件,只要文件很小,它就可以正常工作。
    curl -F "file=@d:/tmp.txt" localhost:8050/upload
    
    curl -F "file=@d:/tmp.txt" localhost:8050/microservice-file-upload/upload
    
    • 而对于大型文件,需要使用一个替代路径绕过/zuul/*中的Spring DispatcherServlet;
      即使用/zuul/*的方式绕过Spring DispatcherServlet(以避免多部分处理)
      curl -F "file=@d:/tmp.txt" localhost:8050/zuul/microservice-file-upload/upload
      
      • application.yml配置中需要加如下语句,主要是为了避免文件过大和上传超时:
      # 经过zuul的请求都会使用hystrix进行包裹
      # hystrix的超时时间
      hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 60000
      # zuul使用了ribbon做负载均衡
      ribbon:
        ConnectTimeout: 3000
        ReadTimeout: 60000
      
      [注] 超时问题解决后,也可能存在堆内存太小,导致上传失败,可以堆tomcat进行如下设置: 点这里

    Disable Zuul Filters

    标题: 禁用zuul过滤器

    SpringCloud在代理和服务器模式下都默认启用了许多ZuulFilter bean。

    有关可以启用的过滤器列表,请参阅Zuul过滤器包

    如果要禁用一个过滤器,请参照如下设置zuul.<SimpleClassName>.<filterType>.disable=true;按照惯例,过滤器后的包是Zuul过滤器类型。

    例如,要禁用org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter需设置zuul.SendResponseFilter.post.disable = true

    展开全文
  • ZooKeeper使用场景

    万次阅读 2018-11-28 21:16:54
    网上对ZooKeeper的使用场景也有不少介绍,本文将结合作者身边的项目例子,系统的对zk的使用场景进行归类介绍。 值得注意的是,ZooKeeper并不是生来就为这些场景设计,都是后来众多开发者根据框架的...

    ZooKeeper是一个高可用的分布式数据管理与系统协调框架。基于对Paxos算法的实现,使该框架保证了分布式环境中数据的强一致性,也正是基于这样的特性,使得ZooKeeper能够应用于很多场景。网上对ZooKeeper的使用场景也有不少介绍,本文将结合作者身边的项目例子,系统的对zk的使用场景进行归类介绍。 值得注意的是,ZooKeeper并不是生来就为这些场景设计,都是后来众多开发者根据框架的特性,摸索出来的典型使用方法。因此,也非常欢迎你分享你在ZooKeeper使用上的奇技淫巧。

    zookeeper实现了主动通知节点变化,原子创建节点,临时节点,按序创建节点等功能。通过以上功能的组合,
    zookeeper能够在分布式系统中组合出很多上层功能。下面就看几个常用到的场景,及使用方式和注意事项。

    名字服务(NameService)

    顾名思义,就是给分布式系统中的资源,使用人易于理解的名字,能够找到需要的资源。例如:一个统一接口系统,接收服务然后转给后端服务的具体server。当新增接口时,请求方只要传递新接口的名字,系统就能够根据名字找到对应的server,发现服务并转发请求。

    在zookeeper中,按照命名的规则,建立对应的目录层级,例如 /company/team/service 就能找到一个公司,一个team下的提供的某个服务的路径。当上线新业务时,服务在zk中找到自己名字的节点,建立一个临时节点,写入配置信息。当调用方使用时,统一接口查询对应目录下的节点,选择合适的读取配置。当业务下掉时,直接删除服务,临时节点自动删除,服务自动下线掉。

    配置管理(Configuration Management)

    分布式系统位于不同主机的服务,有时要使用统一的配置。可以在zookeeper中的znode节点存储配置数据,每个客户端都监控(watch)znode的变化,当配置变更时,会通知推送,然后各个客户端再拉取新的配置。

    注意:zk的watch是一次性的,客户端读取后要重新watch,并且检查是否是最新版本。

    组员管理(Group Membership)

    在Master、Slave模式下,Master要知道都有哪些Slave,进行同步等操作。也要及时知道哪些Slave死掉,然后去做相应处理。具体做法是Master先建立一个/Slave节点,每个Slave上线时都在/Slave建立一个临时节点,写入配置,server监控/Slave节点,对增加或消失的节点进行相应处理。

    以上三种用法都属于配置类服务,按照一定的规则进行配置,需要读取配置的地方监控配置的变化。

    简单互斥锁(Simple Lock)

    每个进程都在/lock下创建锁znode,并watch /lock,只有一个创建成功,当成功的进程释放锁或者停止超时会通知其他进程,重新进入竞争锁的机制。

    互斥锁(Simple Lock without Herd Effect)

    为了不引发惊群效应,只要能给竞争进程排序就可以了,每个进程都在/lock的节点下创建带序号的znode,并且每个znode只监听比他次小的节点,当次小的节点释放锁后,比他次大的节点会收到通知,拿到锁权限。

    注意:防止还没有执行到的进程死掉,要更新监听顺序。例如:2监听1,3监听2,如果2进程提前死掉,3要监控到这种状态,判断是否是2关闭,还是2释放锁,如果不是正常关闭,要去监听1更新监听。

    读写锁(Read/Write Lock)

    读写锁:多个读可以并发执行,但是写和读,写和写不能同时执行。
    改动互斥锁方案,如果是写锁,监听他次小的节点,次小节点释放锁后,写锁检测是否还有更小的节点,如果有继续监听,如果没有获得写锁执行;如果是读锁,监听左侧最大的写锁,当写锁释放后就获得读锁。
    也要注意中间节点死掉提前释放的问题,要重新监听节点。

    屏障(Barrier)

    在分布式系统中,屏障是这样一种语义: 客户端需要等待多个进程完成各自的任务,然后才能继续往前进行下一步。
    例如凌晨备份,等待每个进程把数据都dump结束后,再打包压缩传走。

    client先设置/mybarrier的znode,然后启动每个进程,每个进程执行结束成功后,在/mybarrier下创建结束的znode节点,client发现/mybarrier下的node数都达到了,再继续下面的任务。

    双屏障(Double Barrier)

    双屏障是这样一种语义: 它可以用来同步一个任务的开始和结束,当有足够多的进程进入屏障后,才开始执行任务;当所有的进程都执行完各自的任务后,屏障才撤销。

    进入屏障:创建/ready和/process节点,每个进程都先到ready中注册,注册数量达到要求时,通知所有进程启动开始执行。
    离开屏障:在/process下把注册ready的进程都建立节点,每个进程执行结束后删掉/process下的对应节点。当/process下为空时,任务全结束。

    锁、屏障,本质都是排序,给要使用的节点排序,根据顺序来执行策略,保证执行不冲突。

    总结

    以上的应用场景,并不是只有zk能实现的,而且实现的方式也是通用的,换做其他组件,只要满足了通知和原子创建、自增id,都可以实现这些场景的使用。而且实现的方法也是通用的,不仅在zk中才这样用。
    本质上就是统一配置通知机制,和原子简历自增id节点排序机制,实现了配置类和锁类协调的功能。

    展开全文
  • Unity 使用多场景管理API加载卸载场景 SceneLoader.cs using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.SceneManagement; public class SceneLoader : ...

    Unity 使用多场景管理API加载卸载场景

    创建一个sceneLoad场景在场景上挂载SceneLoader.cs, _load_scene_name 填scene1,
    创建scene1和scene2并挂载SwitchScene.cs,并将scene1的SwitchScene.cs的_next_scene_name填scene2,
    scene2的SwitchScene.cs的_next_scene_name填scene1

    SceneLoader.cs

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.SceneManagement;
    public class SceneLoader : MonoBehaviour
    {
        public string _load_scene_name;
        // Start is called before the first frame update
        void Start()
        {
            SceneManager.LoadScene(_load_scene_name,LoadSceneMode.Additive);
        }
    }
    

    SwitchScene.cs

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.SceneManagement;
    public class SwitchScene : MonoBehaviour
    {
        public string _next_scene_name;
        void OnEnable()
        {
        	// 添加场景加载委托
            SceneManager.sceneLoaded += OnSceneLoaded;
        }
    
        void OnSceneLoaded(Scene scene,LoadSceneMode mode)
        {
            SceneManager.SetActiveScene(SceneManager.GetSceneByName(scene.name)); // 这里不设置的话 SceneManager.GetActiveScene() 会取不到场景 
            Debug.Log("SceneName = " + scene.name);
            Debug.Log("ActiveSceneName = " + SceneManager.GetActiveScene().name);
        }
    
        void OnDisable()
        {
        	// 移除场景委托
            SceneManager.sceneLoaded -= OnSceneLoaded;
        }
    
        public void GoToScene()
        {
        	// 卸载当前场景
            SceneManager.UnloadSceneAsync(SceneManager.GetSceneByName(SceneManager.GetActiveScene().name));
            // 加载下一个场景
            SceneManager.LoadScene(_next_scene_name, LoadSceneMode.Additive);
        }
    
    }
    
    
    
    展开全文
  • Java线程使用场景

    千次阅读 2017-12-08 16:38:16
    使用多线程就一定效率高吗? 有时候使用多线程并不是为了提高效率,而是使得CPU能够同时处理多个事件。 使用场景1 为什么了不阻塞主线程,启动其他线程来做耗时的事情。 比如app开发中耗时的操作都不在UI主线程中...
  • Redis使用场景

    千次阅读 2019-09-27 11:32:38
    文章目录计数器缓存会话缓存全页缓存(FPC)查找表消息队列(发布/订阅功能)分布式锁实现其它 计数器 可以对 String 进行自增自减运算,从而实现...可以使用 Redis 来统一存储台应用服务器的会话信息。 当应用服...
  • Elasticsearch的使用场景深入详解

    万次阅读 多人点赞 2016-08-17 08:40:56
    了解了ES的使用场景,ES的研究、使用、推广才更有价值和意义。1、场景—:使用Elasticsearch作为主要的后端传统项目中,搜索引擎是部署在成熟的数据存储的顶部,以提供快速且相关的搜索能力。这是因为早期的搜索引擎...
  • ExecutorService executorService = Executors.newFixedThreadPool(10);//线程池 CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> { System.out.println("任务一开始");...
  • Android 进程使用场景

    千次阅读 2017-01-12 14:30:30
    推荐资源站:https://zhimalier.com/ 本文章原作者已授权转载 原文地址... 在上一篇《Android 线程介绍》中,我们大概了解了一下Android中的进程的概念以及其生命周期,另外还有Low Memory Kill...
  • Layaair 3D场景使用

    千次阅读 2018-11-29 17:18:50
    unity3d 导出 场景文件 动画的控制 Laya.Sprite3D 脚本的挂载 对于Laya.Sprite3D 碰撞的触发实现     Unity3D 中的场景   程序入口 // 程序入口 class GameMain { constructor(...
  • Unity 多场景打包

    千次阅读 2016-01-25 15:33:49
    作者:cartzhangUnity 多场景打包问题Unity 5.3多场景编辑功能Unity 5.3 有了很好的新功能,不仅仅是VR的功能牛逼啊。多场景编辑对编辑大场景和多人合作处理场景,提供了很大的帮助,效果明显啊。 不用在苦逼的,...
  • Redis-使用场景

    万次阅读 2018-06-06 18:23:40
    Redis是一个key-value存储系统,现在在各种系统中的使用越来越,大部分情况下是因为其高性能的特性,被当做缓存使用,这里介绍下Redis经常遇到的使用场景。 Redis特性 一个产品的使用场景肯定是需要根据产品的...
  • 前言 JavaFX是一个强大的图形和多媒体处理工具包集合,它允许开发者来设计、... 场景(javaFX2.0场景(Scene)分析及使用) 布局 UI组件 2D/3D图形系统(windows vista以下使用directx 9.0,windows7使用dire...
  • ArrayList和LinkedList区别及使用场景

    万次阅读 多人点赞 2018-09-07 18:51:40
    ArrayList和LinkedList区别及使用场景 1. LinkedList和ArrayList的差别主要来自于Array和LinkedList数据结构的不同。ArrayList是基于数组实现的,LinkedList是基于双链表实现的。另外LinkedList类不仅是List接口的...
  • # 通过pecl安装pcntl扩展 sudo pecl install pcntl # 增加 extension=pcntl.so sodo vim /etc/php.ini # 检查扩展是否安装成功 php -m | grep pcntl

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,843,448
精华内容 737,379
关键字:

多场景使用