• Java 编程下的同步代码块


    为了便于理解先来看看没有加同步代码块的 2 组同样功能的代码在不同状态下的执行结果,下面看第一组:

    package cn.sunzn.synchronize;
    
    public class SynchronizeCode {
       public static void main(String[] args) {
           new Thread() {
               public void run() {
                   while (true) {
                       System.out.println("同步代码");
                   }
               };
           }.start();
           new Thread() {
               public void run() {
                   while (true) {
                       System.out.println("SynchronizeCode");
                   }
               };
           }.start();
       }
    }

    第一组代码运行结果:

    SynchronizeCode
    SynchronizeCode
    SynchronizeCode
    SynchronizeCode
    同步代码
    同步代码
    同步代码
    同步代码

    下面再来看第 2 组代码:

    package cn.sunzn.synchronize;
    
    public class SynchronizeCode {
       public static void main(String[] args) {
           new Thread() {
               public void run() {
                   while (true) {
                       System.out.print("同步");
                       System.out.println("代码");
                   }
               };
           }.start();
           new Thread() {
               public void run() {
                   while (true) {
                       System.out.print("Synchronize");
                       System.out.println("Code");
                   }
               };
           }.start();
       }
    }

    第二组代码运行结果:

    同步代码
    同步代码
    同步代码
    同步Code
    SynchronizeCode
    SynchronizeCode
    SynchronizeCode
    SynchronizeCode

    显然,第二组代码中同一个线程下的打印输出并没有同时执行,这是因为 CPU 在不同的线程间进行切换时的随机性导致的。第二组代码中的输出结果“同步Code”是因为 CPU 切换到线程 1 的时候打印输出“同步”,但是当程序正准备打印“代码”的时候,CUP 切换到了线程 2 打印输出“Code”, 然后线程 2 继续持有 CPU 资源进行打印输出,知道 CPU 切换到线程 1。正因为这样的原因,当程序中包含有多个线程时,导致了同一个线程下的代码不能同时被执行。那么,我们如何才能保证这样的情况不发生呢?使用同步代码 块。下面我们来看使用了同步代码块程序的运行结果:

    package cn.sunzn.synchronize;
    
    public class SynchronizeCode {
       public static void main(String[] args) {
           /************ 创建锁对象 ************/
           final Object lock = new Object();
           /************ 开启线程一 ************/
           new Thread() {
               public void run() {
                   while (true) {
                       synchronized (lock) {
                           System.out.print("同步");
                           System.out.println("代码");
                       }
                   }
               };
           }.start();
           /************ 开启线程二 ************/
           new Thread() {
               public void run() {
                   while (true) {
                       synchronized (lock) {
                           System.out.print("Synchronize");
                           System.out.println("Code");
                       }
                   }
               };
           }.start();
       }
    }

    运行上面的代码我们会发现运行结果和第一组代码的运行结果类似,这是因为使用了相同锁对象的同步代码块具有原子性,在进行执行的时候会持续的拥有 CPU 资源直到同步代码块执行完毕,要么继续持有 CPU 资源,要么 CPU 切换到到另一个线程,这样保证了在执行一组代码的时候不会有其他线程插入执行。

  • 相关阅读:
    windows下操作linux虚拟机映射网络驱动器中文件提示chmod权限不足解决方案
    Centos 更改MySQL5.7数据库目录位置
    MySQL语句增加字段,修改字段名,修改类型,修改默认值
    [MySQL]MySQL数据库中如何查询分组后每组中的最后一条记录?
    ROW_NUMBER()函数使用详解
    【转】mysql 存储过程的示例
    简简单单储存过程——循环一个select结果集
    mysql存储过程demo
    mysql日期加一个天数获得新的日期
    使用SyncNavigator轻松实现数据库异地同步、断点续传、异构同步
  • 原文地址:https://www.cnblogs.com/sunzn/p/2910895.html
Copyright © 2020-2023  润新知