synchronized 怎么使用

2023-11-17

文章目录

  • 前言
  • 通过一系列的例子,了解synchronized 使用
  • 总结
前言

上一篇了解了synchronized,但是呢光懂理论没用,关键是要会用,用demo的形式写一下各种使用场景,这么一来,就会对synchronized的使用更加透彻。

通过一系列的例子,了解synchronized 使用
1、synchronized 都会在哪些地方使用?

修饰一个代码块,作用的对象是调用这个代码块的对象。
修饰一个方法,作用的对象是调用这个方法的对象。
修饰一个静态方法,作用是这个类的所有对象。
修饰一个类,作用的是这个类的所有对象

2、怎么使用同步代码块?

两个线程访问同一个对象代码块,只有一个线程执行,另外一个线程被阻塞。
比如:

class MyRunnable implements Runnable{
  private static int count;//定义一个变量count;
  public MyRunnable(){
    count = 0;
  }
  @Override public void run() {
    synchronized (this){//同步代码块,锁住的是MyRunnable这个实例对象
      for (int i = 0; i < 5; i++){
        try {
          System.out.println(Thread.currentThread().getName() + ":" + (count++));
          Thread.sleep(100);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }

    }
  }
  public int getCount(){
    return count;
  }
}

输出的日志如下
2022-12-31 14:36:03.266 8015-8053/com.ssz.mvvmdemo I/System.out: 线程1:0
2022-12-31 14:36:03.366 8015-8053/com.ssz.mvvmdemo I/System.out: 线程1:1
2022-12-31 14:36:03.467 8015-8053/com.ssz.mvvmdemo I/System.out: 线程1:2
2022-12-31 14:36:03.567 8015-8053/com.ssz.mvvmdemo I/System.out: 线程1:3
2022-12-31 14:36:03.667 8015-8053/com.ssz.mvvmdemo I/System.out: 线程1:4
2022-12-31 14:36:03.768 8015-8054/com.ssz.mvvmdemo I/System.out: 线程2:5
2022-12-31 14:36:03.868 8015-8054/com.ssz.mvvmdemo I/System.out: 线程2:6
2022-12-31 14:36:03.968 8015-8054/com.ssz.mvvmdemo I/System.out: 线程2:7
2022-12-31 14:36:04.068 8015-8054/com.ssz.mvvmdemo I/System.out: 线程2:8
2022-12-31 14:36:04.169 8015-8054/com.ssz.mvvmdemo I/System.out: 线程2:9

可以看到先执行线程1,再执行线程2,达到了同步目的。

2.1 这个时候,我们将执行的对象换一下

比如:

    MyRunnable myRunnable = new MyRunnable();
    MyRunnable myRunnable2 = new MyRunnable();
    Thread thread1 = new Thread(myRunnable, "线程1");
    Thread thread2 = new Thread(myRunnable2, "线程2");
    thread1.start();
    thread2.start();

执行结果:
2022-12-31 14:42:33.957 8237-8273/com.ssz.mvvmdemo I/System.out: 线程1:0
2022-12-31 14:42:33.957 8237-8274/com.ssz.mvvmdemo I/System.out: 线程2:1
2022-12-31 14:42:34.057 8237-8273/com.ssz.mvvmdemo I/System.out: 线程1:2
2022-12-31 14:42:34.057 8237-8274/com.ssz.mvvmdemo I/System.out: 线程2:2
2022-12-31 14:42:34.157 8237-8273/com.ssz.mvvmdemo I/System.out: 线程1:3
2022-12-31 14:42:34.157 8237-8274/com.ssz.mvvmdemo I/System.out: 线程2:3
2022-12-31 14:42:34.257 8237-8273/com.ssz.mvvmdemo I/System.out: 线程1:4
2022-12-31 14:42:34.257 8237-8274/com.ssz.mvvmdemo I/System.out: 线程2:4
2022-12-31 14:42:34.358 8237-8274/com.ssz.mvvmdemo I/System.out: 线程2:5
2022-12-31 14:42:34.358 8237-8273/com.ssz.mvvmdemo I/System.out: 线程1:5

可以看到线程1和线程2,变成随机的执行代码块,为什么呢?
因为他们作用的不是同一个对象,线程1 执行的是 myRunnable对象,
而线程2 执行的是 myRunnable2对象。所以他们互不干扰,两个线程就能同时执行。

2.2 当一个线程访问一个对象的 synchronized(this) 代码块的时候,另外一个线程还是可以访问, 该对象的没有被synchronized(this) 修饰的代码块。

比如:

class Counter implements Runnable{
  private int count;
  public Counter(){
    count = 0;
  }

  /**
   * 对count 执行自增操作
   * */
  public void countAdd(){
    synchronized (this){
      for (int i = 0; i < 5; i++){
        try {
          System.out.println(Thread.currentThread().getName()+ ":" + (count++));
          Thread.sleep(100);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
    }
  }
  //没有对count 执行自增操作,只是打印
  public void printCount(){
    for(int i = 0; i < 5; i++){
      try {
        System.out.println(Thread.currentThread().getName() + "  count:" + count);
        Thread.sleep(100);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
  }
  @Override public void run() {
    String threadName = Thread.currentThread().getName();
    if ("线程A".equals(threadName)){//线程A 要执行自增操作
       countAdd();
    }else if("线程B".equals(threadName)){
       printCount();
    }
  }
}

使用:
    Counter counter = new Counter();
    Thread threadA = new Thread(counter, "线程A");
    Thread threadB = new Thread(counter, "线程B");
    threadA.start();
    threadB.start();

结果:
2022-12-31 15:03:52.249 9366-9403/com.ssz.mvvmdemo I/System.out: 线程A:0
2022-12-31 15:03:52.249 9366-9404/com.ssz.mvvmdemo I/System.out: 线程B  count:1
2022-12-31 15:03:52.349 9366-9404/com.ssz.mvvmdemo I/System.out: 线程B  count:1
2022-12-31 15:03:52.349 9366-9403/com.ssz.mvvmdemo I/System.out: 线程A:1
2022-12-31 15:03:52.449 9366-9403/com.ssz.mvvmdemo I/System.out: 线程A:2
2022-12-31 15:03:52.449 9366-9404/com.ssz.mvvmdemo I/System.out: 线程B  count:2
2022-12-31 15:03:52.549 9366-9403/com.ssz.mvvmdemo I/System.out: 线程A:3
2022-12-31 15:03:52.549 9366-9404/com.ssz.mvvmdemo I/System.out: 线程B  count:3
2022-12-31 15:03:52.650 9366-9403/com.ssz.mvvmdemo I/System.out: 线程A:4
2022-12-31 15:03:52.650 9366-9404/com.ssz.mvvmdemo I/System.out: 线程B  count:5

可以看到线程A 和 线程B 他们是互不影响的,线程B还是随机执行的。
也就是说一个线程 在执行同一个对象的 synchronized(this)的代码块时候,
另外一个线程可以执行该对象的没有被synchronized(this)修饰的代码块,不会阻塞。

3、怎么给一个对象加锁呢?
class Account {
  String name;
  float amount;

  public Account(String name, float amount){
    this.name = name;
    this.amount = amount;
  }

  /**
   * 存钱
   * */
  public void save(float money){
    amount += money;
    try {
      Thread.sleep(100);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }

  /**
   * 取钱
   * */
  public void out(float money){
    amount -= money;
    try {
      Thread.sleep(100);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }


  public float getAmount(){
    return amount;
  }
}

class AccountOperator implements Runnable{
  private Account account;
  public AccountOperator(Account account){
    this.account = account;
  }
  @Override public void run() {
    synchronized (account){//对这个对象进行加锁操作
      account.save(500);//存钱500;
      account.out(500);//取钱500;
      System.out.println(Thread.currentThread().getName() + ":" + account.amount);
    }
  }
}

使用:
    Account account = new Account("ssz", 10000.0f);
    AccountOperator accountOperator = new AccountOperator(account);
    final int THREAD_NUM = 10;
    //创建5个线程去随机执行。
    Thread[] threads = new Thread[THREAD_NUM];
    for (int i = 0; i < THREAD_NUM; i++){
      threads[i] = new Thread(accountOperator, "Thread" + i);
      threads[i].start();
    }



结果:
2022-12-31 15:31:09.675 11884-11927/com.ssz.mvvmdemo I/System.out: Thread0:10000.0
2022-12-31 15:31:09.875 11884-11928/com.ssz.mvvmdemo I/System.out: Thread1:10000.0
2022-12-31 15:31:10.076 11884-11930/com.ssz.mvvmdemo I/System.out: Thread2:10000.0
2022-12-31 15:31:10.276 11884-11931/com.ssz.mvvmdemo I/System.out: Thread3:10000.0
2022-12-31 15:31:10.477 11884-11934/com.ssz.mvvmdemo I/System.out: Thread5:10000.0
2022-12-31 15:31:10.677 11884-11932/com.ssz.mvvmdemo I/System.out: Thread4:10000.0
2022-12-31 15:31:10.878 11884-11936/com.ssz.mvvmdemo I/System.out: Thread7:10000.0
2022-12-31 15:31:11.078 11884-11937/com.ssz.mvvmdemo I/System.out: Thread8:10000.0
2022-12-31 15:31:11.279 11884-11938/com.ssz.mvvmdemo I/System.out: Thread9:10000.0
2022-12-31 15:31:11.480 11884-11935/com.ssz.mvvmdemo I/System.out: Thread6:10000.0

可以看到线程是随机的执行,但是呢,对于存钱取钱的操作仍然是不受影响的,因为这块是进行了同步存取操作,是对Account进行了加锁操作,保证了不受其他线程的干扰。

3.1 假如没有明确的对象作为锁,只想同步一段代码块怎么办呢?
class Test implements Runnable{
  private byte[] lock = new byte[0]//一个特殊的实例对象

  public void test(){
    synchronized(lock){
        //todo 要同步的代码
    }
  }

  public void run(){
  }

}

为什么使用byte[] 作为对象呢?
因为byte 数组创建起来比任何对象都经济。
跟Object object = new Object() 比起来的话,查看编译后的字节码发现。
byte 数组 只需要3行操作码,而 object 需要7行操作码

3.2 synchronized 在修饰方法的时候能不能继承呢?

synchronized 是不能继承的,也就是如果子类要同步,
要嘛调用父类的同步方法,要嘛就是在方法前,添加一个synchronized关键字。
比如:

class Parent {
   public synchronized void method() {   }
}
class Child extends Parent {
   public void method() { super.method();   }//调用父类的同步方法
}

class Parent {
   public synchronized void method() { }
}
class Child extends Parent {
   public synchronized void method() { } //添加关键字
}

4、怎么修饰一个静态方法呢?

当我们在修饰静态方法的时候,因为静态方法是属于类的,所以锁住的是类的所有对象。
比如:

class NewRunnable implements Runnable{
  private static int count;
  public NewRunnable(){
    count = 0;
  }

  public synchronized static void method(){  //修饰的是一个静态方法
    for (int i = 0; i < 5; i++){
      try {
        System.out.println(Thread.currentThread().getName() + ":" + (count++));
        Thread.sleep(100);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
  }

  @Override public void run() {
    method();
  }
}

使用:
    NewRunnable newRunnable = new NewRunnable();
    NewRunnable newRunnable2 = new NewRunnable();
    Thread thread1 = new Thread(newRunnable, "线程1"); //newRunnable
    Thread thread2 = new Thread(newRunnable2, "线程2");//newRunnable2
    thread1.start();
    thread2.start();

结果:
2022-12-31 17:02:21.483 20792-20824/com.ssz.mvvmdemo I/System.out: 线程1:0
2022-12-31 17:02:21.583 20792-20824/com.ssz.mvvmdemo I/System.out: 线程1:1
2022-12-31 17:02:21.683 20792-20824/com.ssz.mvvmdemo I/System.out: 线程1:2
2022-12-31 17:02:21.783 20792-20824/com.ssz.mvvmdemo I/System.out: 线程1:3
2022-12-31 17:02:21.884 20792-20824/com.ssz.mvvmdemo I/System.out: 线程1:4
2022-12-31 17:02:21.984 20792-20825/com.ssz.mvvmdemo I/System.out: 线程2:5
2022-12-31 17:02:22.084 20792-20825/com.ssz.mvvmdemo I/System.out: 线程2:6
2022-12-31 17:02:22.184 20792-20825/com.ssz.mvvmdemo I/System.out: 线程2:7
2022-12-31 17:02:22.285 20792-20825/com.ssz.mvvmdemo I/System.out: 线程2:8
2022-12-31 17:02:22.385 20792-20825/com.ssz.mvvmdemo I/System.out: 线程2:9

可以看到,虽然是不同的对象,但是呢,却还是按顺序执行了。最主要是同步的是静态方法,而静态方法是属于类的,这相当于锁住了这个类,所以,就能阻止其他线程调用,只能等待第一个线程执行完,再执行第二个线程。

4.1 怎么修饰一个类呢?

我们对上面修饰静态方法做个改造,就是把synchronized 放到方法里头,然后使用 synchronized (NewRunnable.class)
比如:

class NewRunnable implements Runnable{
  private static int count;
  public NewRunnable(){
    count = 0;
  }

  public void method(){    //不是静态方法,就是普通方法
    synchronized (NewRunnable.class){ //锁的作用对象是类
      for (int i = 0; i < 5; i++){
        try {
          System.out.println(Thread.currentThread().getName() + ":" + (count++));
          Thread.sleep(100);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
    }
  }

  @Override public void run() {
    method();
  }
}
结果情况1:
2022-12-31 17:10:52.476 22805-22840/com.ssz.mvvmdemo I/System.out: 线程2:0
2022-12-31 17:10:52.577 22805-22840/com.ssz.mvvmdemo I/System.out: 线程2:1
2022-12-31 17:10:52.677 22805-22840/com.ssz.mvvmdemo I/System.out: 线程2:2
2022-12-31 17:10:52.778 22805-22840/com.ssz.mvvmdemo I/System.out: 线程2:3
2022-12-31 17:10:52.878 22805-22840/com.ssz.mvvmdemo I/System.out: 线程2:4
2022-12-31 17:10:52.978 22805-22839/com.ssz.mvvmdemo I/System.out: 线程1:5
2022-12-31 17:10:53.078 22805-22839/com.ssz.mvvmdemo I/System.out: 线程1:6
2022-12-31 17:10:53.179 22805-22839/com.ssz.mvvmdemo I/System.out: 线程1:7
2022-12-31 17:10:53.279 22805-22839/com.ssz.mvvmdemo I/System.out: 线程1:8
2022-12-31 17:10:53.379 22805-22839/com.ssz.mvvmdemo I/System.out: 线程1:9

结果情况2:
2022-12-31 17:12:17.787 23462-23496/com.ssz.mvvmdemo I/System.out: 线程1:0
2022-12-31 17:12:17.887 23462-23496/com.ssz.mvvmdemo I/System.out: 线程1:1
2022-12-31 17:12:17.987 23462-23496/com.ssz.mvvmdemo I/System.out: 线程1:2
2022-12-31 17:12:18.087 23462-23496/com.ssz.mvvmdemo I/System.out: 线程1:3
2022-12-31 17:12:18.187 23462-23496/com.ssz.mvvmdemo I/System.out: 线程1:4
2022-12-31 17:12:18.288 23462-23497/com.ssz.mvvmdemo I/System.out: 线程2:5
2022-12-31 17:12:18.388 23462-23497/com.ssz.mvvmdemo I/System.out: 线程2:6
2022-12-31 17:12:18.489 23462-23497/com.ssz.mvvmdemo I/System.out: 线程2:7
2022-12-31 17:12:18.589 23462-23497/com.ssz.mvvmdemo I/System.out: 线程2:8
2022-12-31 17:12:18.689 23462-23497/com.ssz.mvvmdemo I/System.out: 线程2:9

我们看到可能先执行的线程1,也可能先执行的线程2,但是不管是谁开始执行,只要谁先开始,另外一个线程就得等着。
所以,这就保证了同步。
这里是给这个类加锁,所以他们都是共用1把锁,只有一方把锁释放,另外一方才能执行。

5 使用synchronized 有哪些注意点呢?

1、定义接口的时候,不能使用synchronized 关键字。
2、构造方法不能使用synchronized 关键字,但可以使用synchronized来同步代码块。

总结

总的来讲:
1、synchronized 关键字用在非静态的方法上,或者对象上,所获得的锁是针对对象的;
如果是一个静态方法,或者一个类,那么锁是针对类的所有对象的。
2、每个对象只有一把锁与之关联,需要等一方释放,另一方才能执行。
3、使用同步是需要系统很大开销的,所以非必要情况下不要进行同步锁操作。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

synchronized 怎么使用 的相关文章

  • Java 中等效的并行扩展

    我在 Net 开发中使用并行扩展有一些经验 但我正在考虑在 Java 中做一些工作 这些工作将受益于易于使用的并行库 JVM 是否提供任何与并行扩展类似的工具 您应该熟悉java util concurrent http java sun
  • 如何为最终用户方便地启动Java GUI程序

    用户想要从以下位置启动 Java GUI 应用程序Windows 以及一些额外的 JVM 参数 例如 javaw Djava util logging config file logging properties jar MyGUI jar
  • 给定两个 SSH2 密钥,我如何检查它们是否属于 Java 中的同一密钥对?

    我正在尝试找到一种方法来验证两个 SSH2 密钥 一个私有密钥和一个公共密钥 是否属于同一密钥对 我用过JSch http www jcraft com jsch 用于加载和解析私钥 更新 可以显示如何从私钥 SSH2 RSA 重新生成公钥
  • 在 HTTPResponse Android 中跟踪重定向

    我需要遵循 HTTPost 给我的重定向 当我发出 HTTP post 并尝试读取响应时 我得到重定向页面 html 我怎样才能解决这个问题 代码 public void parseDoc final HttpParams params n
  • 制作一个交互式Windows服务

    我希望我的 Java 应用程序成为交互式 Windows 服务 用户登录时具有 GUI 的 Windows 服务 我搜索了这个 我发现这样做的方法是有两个程序 第一个是服务 第二个是 GUI 程序并使它们进行通信 服务将从 GUI 程序获取
  • 无法展开 RemoteViews - 错误通知

    最近 我收到越来越多的用户收到 RemoteServiceException 错误的报告 我每次给出的堆栈跟踪如下 android app RemoteServiceException Bad notification posted fro
  • JavaMail 只获取新邮件

    我想知道是否有一种方法可以在javamail中只获取新消息 例如 在初始加载时 获取收件箱中的所有消息并存储它们 然后 每当应用程序再次加载时 仅获取新消息 而不是再次重新加载它们 javamail 可以做到这一点吗 它是如何工作的 一些背
  • 路径中 File.separator 和斜杠之间的区别

    使用有什么区别File separator和一个正常的 在 Java 路径字符串中 与双反斜杠相反 平台独立性似乎不是原因 因为两个版本都可以在 Windows 和 Unix 下运行 public class SlashTest Test
  • 如何为俚语和表情符号构建正则表达式 (regex)

    我需要构建一个正则表达式来匹配俚语 即 lol lmao imo 等 和表情符号 即 P 等 我按照以下示例进行操作http www coderanch com t 497238 java java Regular Expression D
  • 从 127.0.0.1 到 2130706433,然后再返回

    使用标准 Java 库 从 IPV4 地址的点分字符串表示形式获取的最快方法是什么 127 0 0 1 到等效的整数表示 2130706433 相应地 反转所述操作的最快方法是什么 从整数开始2130706433到字符串表示形式 127 0
  • 加密 JBoss 配置中的敏感信息

    JBoss 中的标准数据源配置要求数据库用户的用户名和密码位于 xxx ds xml 文件中 如果我将数据源定义为 c3p0 mbean 我会遇到同样的问题 是否有标准方法来加密用户和密码 保存密钥的好地方是什么 这当然也与 tomcat
  • 如何在控制器、服务和存储库模式中使用 DTO

    我正在遵循控制器 服务和存储库模式 我只是想知道 DTO 在哪里出现 控制器应该只接收 DTO 吗 我的理解是您不希望外界了解底层域模型 从领域模型到 DTO 的转换应该发生在控制器层还是服务层 在今天使用 Spring MVC 和交互式
  • Eclipse Java 远程调试器通过 VPN 速度极慢

    我有时被迫离开办公室工作 这意味着我需要通过 VPN 进入我的实验室 我注意到在这种情况下使用 Eclipse 进行远程调试速度非常慢 速度慢到调试器需要 5 7 分钟才能连接到远程 jvm 连接后 每次单步执行断点 行可能需要 20 30
  • Google App Engine 如何预编译 Java?

    App Engine 对应用程序的 Java 字节码使用 预编译 过程 以增强应用程序在 Java 运行时环境中的性能 预编译代码的功能与原始字节码相同 有没有详细的信息这是做什么的 我在一个中找到了这个谷歌群组消息 http groups
  • 如何从指定日期获取上周五的日期? [复制]

    这个问题在这里已经有答案了 如何找出上一个 上一个 星期五 或指定日期的任何其他日期的日期 public getDateOnDay Date date String dayName 我不会给出答案 先自己尝试一下 但是 也许这些提示可以帮助
  • 玩!框架:运行“h2-browser”可以运行,但网页不可用

    当我运行命令时activator h2 browser它会使用以下 url 打开浏览器 192 168 1 17 8082 但我得到 使用 Chrome 此网页无法使用 奇怪的是它以前确实有效 从那时起我唯一改变的是JAVA OPTS以启用
  • 有没有办法为Java的字符集名称添加别名

    我收到一个异常 埋藏在第 3 方库中 消息如下 java io UnsupportedEncodingException BIG 5 我认为发生这种情况是因为 Java 没有定义这个名称java nio charset Charset Ch
  • 当我从 Netbeans 创建 Derby 数据库时,它存储在哪里?

    当我从 netbeans 创建 Derby 数据库时 它存储在哪里 如何将它与项目的其余部分合并到一个文件夹中 右键单击Databases gt JavaDB in the Service查看并选择Properties This will
  • 将 List 转换为 JSON

    Hi guys 有人可以帮助我 如何将我的 HQL 查询结果转换为带有对象列表的 JSON 并通过休息服务获取它 这是我的服务方法 它返回查询结果列表 Override public List
  • 按日期对 RecyclerView 进行排序

    我正在尝试按日期对 RecyclerView 进行排序 但我尝试了太多的事情 我不知道现在该尝试什么 问题就出在这条线上适配器 notifyDataSetChanged 因为如果我不放 不会显示错误 但也不会更新 recyclerview

随机推荐

  • JVM 内存分析—优化

    参考链接 https www jianshu com p c6e2abb9f657 JVM及GC https blog csdn net sltylzx article details 90704205 在Eclipse上安装MAT Mem
  • kafka学习指南(总结版)

    版本介绍 从使用上来看 以0 9为分界线 0 9开始不再区分高级 低级消费者API 从兼容性上来看 以0 8 x为分界线 0 8 x不兼容以前的版本 总体拓扑架构 从上可知 1 生产者不需要访问zookeeper 2 消费者fetch消息
  • 利用PDB文件将蛋白中的单聚体利用对称矩阵转换为二聚体

    下面是需要在VMD中执行的tcl脚本 steps source mono2poly tcl mol delete all mol new filename pdb set sel atomselect top all set matrix
  • Divide by three, multiply by two CodeForces - 977D(dfs vector记录答案并利用vector回溯)

    em 虽然自己想到了dfs回溯解决这个问题 结果却咋实现 记录答案但是如果答案不对 答案也要回溯 这个问题上翻了车 原谅菜鸡我没有想到可以直接v pop back em 以前基本没用过这个功能 这里记录一下 参考了大佬代码 AC代码 inc
  • Java 通过HttpURLConnection Post方式提交json,并从服务端返回json数据

    这个技术和xml差不过 主要是服务端代码稍微修改 客户端代码修改部分传递参数就可以完成 但在之前需要导入json所需要的jar包 PostJson java代码 package PostPager import java io InputS
  • torch.sigmoid() 与 torch.nn.Sigmoid() 对比 python

    1 torch sigmoid 2 torch nn Sigmoid 只看文档 我没太看出二者的具体区别 通过以下可知得到结果自然相同 不过使用方式确实不同 我目前也没明白为啥
  • vscode 添加万能头文件#include<bits/stdc++.h>

    文章目录 前言 配置 前言 有一天我在愉快的刷着leetcode 突然觉得写头文件好TM麻烦 于是就想着配置一下万能头文件 配置的过程我觉得还是记录一下吧 很多初学者可能会犯迷糊 配置 首先 我们要清楚 我们在vscode上写C C 程序的
  • 给element datetimepicker 设置默认当前时间

    else里面就是设置默认当前时间15分钟后 watch row val this liveTime 当时间不为空时才回显 if val liveBeginTime val liveEndTime this liveTime push new
  • 阿里云P2P内容分发网络(PCDN)实操手册

    一 PCDN是定义 P2P 内容分发网络 英文名 P2P CDN 以下简称PCDN 是以P2P技术为基础 通过挖掘利用电信边缘网络海量碎片化闲置资源而构建的低成本高品质内容分发网络服务 客户通过集成PCDN SDK 以下简称SDK 接入该服
  • 关于scroll和mousewheel事件的问题

    需要注意的点 火狐的鼠标滚轮事件是DOMMouseScroll 事件参数兼容 e window event e 下面省略 preventDefault 函数取消的是默认事件 不会把我们自己添加的事件处理删除 实验开始 在下面验证例子的基础上
  • Android仿网页分页效果

    比较简单的一个方法 使用gridview来做的效果 1 在adapter中的getCount中判断list size是否你需要显示的长度 小于使用list size大于使用你需要的长度 我这里的长度为10 所以判断的为10 2 在adapt
  • 深度学习的核心理念

    深度学习的方法 核心是拟合 拟合的意思 是指在一个被定义的度量空间里 用一个函数 比较准确地表示一堆现有的空间数据 让拟合后误差尽量变小 贴合的越近越好 为何又说深度学习是统计呢 这个观点 跟拟合是同一个意思的不同表述 一理各表 在一个 给
  • GIoU详解

    Generalized Intersection over Union A Metric and A Loss for Bounding Box Regression 一 动机 在目标检测任务中 回归loss相同的情况下 IoU却可能大不相
  • LeetCode第125题解析

    给定一个字符串 验证它是否是回文串 只考虑字母和数字字符 可以忽略字母的大小写 说明 本题中 我们将空字符串定义为有效的回文串 示例 1 输入 A man a plan a canal Panama 输出 true 示例 2 输入 race
  • 梦想世界3手游服务器维护,2021年4月1日官方维护公告

    2021年4月1日官方维护公告 发布时间 2021 04 01 新增内容 1 主角换新 新增主角新模型资源 维护前已有角色玩家可在 奖励 主角换新 界面进行转换操作 可选择保留现有模型 维护后新创建的角色将默认使用主角新模型 2 仙兽转换功
  • excel导出内存溢出_轻松解决PHPExcel导出10W行超时和内存溢出问题

    专题1 PHPExcel的疑难杂症各个击破 本文使用了一个轻量级的PHP的Excel操作库 PHP XLSXWriter 一 解决行的问题 10w行excel数据导出仅需要5 26秒 再也不用担心excel导出超过1w行就超时 php in
  • 情感分析研究的新视野

    点击上方 AI公园 关注公众号 选择加 星标 或 置顶 作者 Caroline Brun 编译 ronghuaiyang 导读 对情感分析研究领域做了非常好的总结和展望 假新闻 受欢迎程度 健康状况 金融和社会风险 情感分析正在帮助理解这一
  • 入门级动态规划五步法(斐波那契数)

    1 确定dp数组 dp table 以及下标的含义 2 确定递推公式 3 dp数组如何初始化 4 确定遍历顺序 5 举例推导dp数组 class Solution def fib self n int gt int if n 0 retur
  • 记一次 Centos7 cmake 版本升级(由 v2.8.12.2 升级至 v3.14.5)

    一 基本信息说明 官网 https cmake org 下载地址 https cmake org files 二 系统 工具 1 系统版本 Centos7 5 CentOS 7 x86 64 Minimal 1804 2 工具 xshell
  • synchronized 怎么使用

    文章目录 前言 通过一系列的例子 了解synchronized 使用 总结 前言 上一篇了解了synchronized 但是呢光懂理论没用 关键是要会用 用demo的形式写一下各种使用场景 这么一来 就会对synchronized的使用更加