posts - 37,  comments - 68,  views - 78万
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

为了保证数据的一致性即实现线程的安全性,java虚拟机提供了同步和锁机制。synchronized关键字是最基本的互斥同步手段。除此之外,还可以使用java.util.concurrent包中的重入锁(ReentrantLock)来实现同步。相比synchronized,ReentrantLock增加了一些高级功能,主要有等待可中断、可实现公平锁、锁可以绑定多个条件等。

见SynchronizedDemo.java的源码理解synchronized

复制代码
/**
 * Synchronized理解:
 *    根据如下4个例子总结如下:
 * Synchronized修饰的方法和Synchronized(this)修饰的代码块功能是一样的,当使用Synchronized修饰的方法或Synchronized(this)修饰的代码块被调用时,当前的实例对象被锁住,因此没有其他线程可以调用该实例对象的这个或任何其他的Synchronized修饰的方法和Synchronized(this)修饰的代码块
 * static Synchronized修饰的方法和Synchronized(*.class)修饰的代码块功能是一样的,当使用static Synchronized修饰的方法或Synchronized(*.class)修饰的代码块被调用时,当前的类对象(例子中的是Sync.class对象)被锁住,因此没有其他线程可以调用同一个类的的这个或任何其他的static Synchronized修饰的方法和Synchronized(*.class)修饰的代码块
 **/
public class SynchronizedDemo{
    /**
     * 例1:
     * 同一个对象:
     * 当一个线程进入一个对象A的synchronized方法的同时,其它线程不能进入该对象的任何synchronized方法
     **/
    private void showSynchronizedResult1(){
        final Sync testSync1 = new Sync();
     
        Thread thread1 = new Thread(new Runnable(){
            @Override
            public void run(){
                testSync1.run1();
            }
        });

        Thread thread2 = new Thread(new Runnable(){
            @Override
            public void run(){
                testSync1.run2();
            }
        });

        thread1.start();
        thread2.start();
    }
    
    /**
     * 例2:
     * 同一个对象:
     * 当一个线程进入一个对象A的synchronized方法的同时,其它线程可以进入该对象的普通方法
     **/
    private void showSynchronizedResult2(){
        final Sync testSync1 = new Sync();
     
        Thread thread1 = new Thread(new Runnable(){
            @Override
            public void run(){
                testSync1.run1();
            }
        });

        Thread thread3 = new Thread(new Runnable(){
            @Override
            public void run(){
                testSync1.run3();
            }
        });

        thread1.start();
        thread3.start();
    }
    
    /**
     * 例3:
     * 不同对象 
     * 当一个线程进入一个对象A的synchronized方法的同时,其它线程可以进入其他对象的synchronized方法,互不影响
     **/
    private void showSynchronizedResult3(){
        final Sync testSync1 = new Sync();
        final Sync testSync2 = new Sync();
     
        Thread thread1 = new Thread(new Runnable(){
            @Override
            public void run(){
                testSync1.run1();
            }
        });

        Thread thread2 = new Thread(new Runnable(){
            @Override
            public void run(){
                testSync2.run2();
            }
        });

        thread1.start();
        thread2.start();
    }
    
    /**
     * 例4:
     * 当一个线程进入一个static synchronized方法的同时,其它线程不可以进入任何的static synchronized方法
     **/
    private void showStaticSynchronizedResult4(){
        Thread thread1 = new Thread(new Runnable(){
            @Override
            public void run(){
                Sync.run4();
            }
        });

        Thread thread2 = new Thread(new Runnable(){
            @Override
            public void run(){
                Sync.run5();
            }
        });

        thread1.start();
        thread2.start();
    }
    
    public static void main(String args[]){
        // 例1:多线程下同一对象的多个Synchronized方法
        new SynchronizedDemo().showSynchronizedResult1();
        
        // 例2:多线程下同一对象的Synchronized方法和普通方法
        //new SynchronizedDemo().showSynchronizedResult2();
        
        // 例3:多线程下不同对象的Synchronized方法
        //new SynchronizedDemo().showSynchronizedResult3();
        
        // 例4:多线程下的多个static Synchronized方法
        //new SynchronizedDemo().showStaticSynchronizedResult4();
    }
}

class Sync{
    public synchronized void run1(){
        for (int i = 0; i < 5; i++){
            System.out.println("execute run1");
            sleepOneSec();
        }
    }

    public synchronized void run2(){
        for (int i = 0; i < 5; i++){
            System.out.println("execute run2");
            sleepOneSec();
        }
    }
    
    public void run3(){
        for (int i = 0; i < 5; i++){
            System.out.println("execute run3");
            sleepOneSec();
        }
    }
    
    public static synchronized void run4(){
        for (int i = 0; i < 5; i++){
            System.out.println("execute run4");
            sleepOneSec();
        }
    }

    public static synchronized void run5(){
        for (int i = 0; i < 5; i++){
            System.out.println("execute run5");
            sleepOneSec();
        }
    }
    
    private static void sleepOneSec(){
        try{
            Thread.sleep(1000);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
    }
}
复制代码

 

posted on   alex_wongh  阅读(187)  评论(0编辑  收藏  举报
编辑推荐:
· dotnet 源代码生成器分析器入门
· ASP.NET Core 模型验证消息的本地化新姿势
· 对象命名为何需要避免'-er'和'-or'后缀
· SQL Server如何跟踪自动统计信息更新?
· AI与.NET技术实操系列:使用Catalyst进行自然语言处理
阅读排行:
· 官方的 MCP C# SDK:csharp-sdk
· 一款 .NET 开源、功能强大的远程连接管理工具,支持 RDP、VNC、SSH 等多种主流协议!
· 提示词工程师自白:我如何用一个技巧解放自己的生产力
· 一文搞懂MCP协议与Function Call的区别
· 如何不购买域名在云服务器上搭建HTTPS服务
点击右上角即可分享
微信分享提示