java中的synchronized实例(代码块)

    上篇博客中简短的回顾了一下基础知识,这篇博客看看SyncThread修饰代码块的实例。

    修饰一段代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象;

    一个线程访问一个对象中的synchronized(this)同步代码块时,其他试图访问该对象的线程将被阻塞。我们看下面一个例子

public class SyncThread implements Runnable{
  private static int count;
 
   publicSyncThread() {
     count = 0;
   }
 
   public void run() { 
  //加锁的同步代码块
     synchronized(this) {
        for (int i = 0; i < 5; i++) {
           try {
              System.out.println(Thread.currentThread().getName() + ":" +(count++));
              Thread.sleep(1000);
           } catch (InterruptedException e) {
              e.printStackTrace();
           }
         }
      }
 
   }
 
   publicint getCount() {
     return count;
   }
 
    public static void main(String[] args){
        SyncThreadsyncThread = new SyncThread();
        Threadthread1 = new Thread(syncThread, "SyncThread1");
        Threadthread2 = new Thread(syncThread, "SyncThread2");
        thread1.start();
        thread2.start();
    }
}

运行结果:


分析:

     当两个并发线程(thread1和thread2)访问同一个对象(syncThread)中的synchronized代码块时,在同一时刻只能有一个线程得到执行,另一个线程受阻塞,必须等待当前线程执行完这个代码块以后才能执行该代码块。


修改一部分代码:

public static void main(String[] args){
        SyncThreadsyncThread1 = new SyncThread();
        SyncThreadsyncThread2 = new SyncThread();
        Threadthread1 = new Thread(syncThread1, "SyncThread1");
        Threadthread2 = new Thread(syncThread2, "SyncThread2");
        thread1.start();
        thread2.start();
}


结果:这次是一个线程一次交替进行的,这是为什么呢


分析:

     这次创建了两个SyncThread的对象syncThread1和syncThread2,线程thread1执行的是syncThread1对象中的synchronized代码(run),而线程thread2执行的是syncThread2对象中的synchronized代码(run); synchronized锁定的是对象,这时会有两把锁分别锁定syncThread1对象和syncThread2对象,而这两把锁是互不干扰的,不形成互斥,所以两个线程可以同时执行。


小结:

    Synchronized锁定的是对象,当只实例化一个对象时执行到同步代码块同一时刻只能够有一个线程执行该代码块,如果实例化了多个不同的线程可以调用不同实例化对象中的同步代码块。这应该也就是为什么要使用单例控制类的实例化,可以使线程更加安全。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
synchronized 关键字是 Java 的一个关键字,用于实现并发编程的同步。它可以用于方法、代码块和静态方法上。 1. 用法一:修饰实例方法 当一个线程访问一个对象的 synchronized 实例方法时,其他线程不能访问该对象的其他 synchronized 实例方法,但可以访问该对象的非 synchronized 实例方法。这种方式的锁是当前实例对象。 示例代码: ```java public synchronized void syncMethod() { // synchronized 代码块 } ``` 2. 用法二:修饰代码块 synchronized 代码块可以用来同步访问共享资源,它必须接收一个对象作为参数,该对象被称为锁对象。当线程进入 synchronized 代码块时,它必须获得锁对象的锁,其他线程在此时无法获得锁对象的锁,只有等待锁被释放。 示例代码: ```java public void syncBlock() { synchronized(this) { // synchronized 代码块 } } ``` 3. 用法三:修饰静态方法 当一个线程访问一个类的 synchronized 静态方法时,其他线程不能访问该类的其他 synchronized 静态方法,但可以访问该类的非 synchronized 静态方法。这种方式的锁是当前类的 Class 对象。 示例代码: ```java public static synchronized void syncStaticMethod() { // synchronized 代码块 } ``` 需要注意的是,使用 synchronized 关键字会降低程序的性能,因为当一个线程获得锁时,其他线程必须等待该线程释放锁才能继续执行,这会增加线程的上下文切换和调度开销。因此,在进行并发编程时,应该尽量避免使用 synchronized 关键字,而是使用更高级别的同步机制,如 Lock、Semaphore、CountDownLatch 等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值