JAVA synchronized关键字锁机制(中)

synchronized 锁机制简单的用法,高效的执行效率使成为解决线程安全的首选。 下面总结其特性以及使用技巧,加深对其理解。

特性:

  1. Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。

      2. 当一个线程同时访问object的一个synchronized(this)同步代码块时,其它线程仍然可以访问非修饰的方法或代码块。

      3. 当多个线程同时访问object的synchronized(this)同步代码块时,会存在互斥访问,其它线程会阻塞直到获取锁。

      4. 当线程访问object的synchronized(this)同步代码块时,同一个线程可以多次获取锁,当然也不需要释放多次。获取和释放必须相同。

      5. 所有的对象都可以获取锁,也可以释放锁。

      6. 所有的类也可以获取锁和释放锁,因此静态方法也可以加锁。而特性同上。

猜想:

     在jvm中对每个对象都有一个记录锁的状态,当同一个线程访问锁时候就会累加,其它线程访问要等到状态变为未锁状态,当让相同线程释放锁会累减。

 质疑:

    那么对于类锁来说,应该是所有对象都可以获取锁,那么锁是全局的对所有对象都有效?

public class SynchronizedMtdTest {

  public static void main(String[] args) {

    new Thread(new Runnable() {
      @Override
      public void run() {
        SynchronizedMtdTest.appendStr();
      }
    }).start();
    new Thread(new Runnable() {
      @Override
      public void run() {
        SynchronizedMtdTest.printStr();
      }
    }).start();
    new Thread(new Runnable() {
      @Override
      public void run() {
        SynchronizedMtdTest synchronizedMtdTest = new SynchronizedMtdTest();
        synchronizedMtdTest.appendStr();
      }
    }).start();
    new Thread(new Runnable() {
      @Override
      public void run() {
        SynchronizedMtdTest synchronizedMtdTest = new SynchronizedMtdTest();
        synchronizedMtdTest.printStr();
      }
    }).start();
    new Thread(new Runnable() {
      @Override
      public void run() {
        SynchronizedMtdTest synchronizedMtdTest = new SynchronizedMtdTest();
        synchronizedMtdTest.append();
      }
    }).start();
  }

  public synchronized static void appendStr() {
    System.out.println("pid=" + Thread.currentThread().getId() + "------appendStr------");
    try {
      Thread.sleep(1000);
      System.out.println("pid=" + Thread.currentThread().getId() + "------appendStr1000------");
    } catch (InterruptedException e) {
      e.printStackTrace();
    }

  }

  public static void append() {
    System.out.println("pid=" + Thread.currentThread().getId() + "------append------");
    try {
      Thread.sleep(3000);
      System.out.println("pid=" + Thread.currentThread().getId() + "------append3000------");
    } catch (InterruptedException e) {
      e.printStackTrace();
    }

  }

  public synchronized static void printStr() {
    System.out.println("pid=" + Thread.currentThread().getId() + "------printStr------");
    try {
      Thread.sleep(6000);
      System.out.println("pid=" + Thread.currentThread().getId() + "------printStr6000------");
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }

}

结果:

pid=10------appendStr------
pid=14------append------
pid=10------appendStr1000------
pid=13------printStr------
pid=14------append3000------
pid=13------printStr6000------
pid=12------appendStr------
pid=12------appendStr1000------
pid=11------printStr------
pid=11------printStr6000------

分析结果可以看出对于静态方法加锁,所有的线程调用方法,不管怎样都会互斥,而为加锁不会互斥。

因此:

对于类锁来说应该在持久代也就是方法区有对具体类也有加锁机制,而且原理同对象锁。

那么:

    可见,上面可以做如下修改达到相同效果。

public static void appendStr() {
    synchronized (SynchronizedMtdTest.class) {
      System.out.println("pid=" + Thread.currentThread().getId() + "------appendStr------");
      try {
        Thread.sleep(1000);
        System.out.println("pid=" + Thread.currentThread().getId() + "------appendStr1000------");
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
  }

  public static void printStr() {
    synchronized (SynchronizedMtdTest.class) {
      System.out.println("pid=" + Thread.currentThread().getId() + "------printStr------");
      try {
        Thread.sleep(6000);
        System.out.println("pid=" + Thread.currentThread().getId() + "------printStr6000------");
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
  }

结果:

pid=10------appendStr------
pid=10------appendStr1000------
pid=13------printStr------
pid=13------printStr6000------
pid=12------appendStr------
pid=12------appendStr1000------
pid=11------printStr------
pid=11------printStr6000------
时间: 2024-12-22 21:58:41

JAVA synchronized关键字锁机制(中)的相关文章

Java Synchronized 关键字

本文内容 Synchronized 关键字 示例 Synchronized 方法 内部锁(Intrinsic Locks)和 Synchronization 参考资料 下载 Demo Synchronized 关键字 Java 语言提供两个基本的同步机制:synchronized 方法(synchronized methods )和 synchronized  语句(synchronized statements). 示例 先大概说一下 Java Synchronized 关键字,当它用来修饰一

Java synchronized 关键字详解

Java synchronized 关键字详解 前置技能点 进程和线程的概念 线程创建方式 线程的状态状态转换 线程安全的概念 synchronized 关键字的几种用法 修饰非静态成员方法 synchronized public void sync(){ } 修饰静态成员方法 synchronized public static void sync(){ } 类锁代码块 synchronized (类.class){ } 对象锁代码块 synchronized (this|对象){ } syn

深入浅出Java并发包—锁机制(三)

接上文<深入浅出Java并发包—锁机制(二)>  由锁衍生的下一个对象是条件变量,这个对象的存在很大程度上是为了解决Object.wait/notify/notifyAll难以使用的问题. 条件(也称为条件队列 或条件变量)为线程提供了一个含义,以便在某个状态条件现在可能为 true 的另一个线程通知它之前,一直挂起该线程(即让其“等待”).因为访问此共享状态信息发生在不同的线程中,所以它必须受保护,因此要将某种形式的锁与该条件相关联.等待提供一个条件的主要属性是:以原子方式 释放相关的锁,并

深入浅出Java并发包—锁机制(二)

接上文<深入浅出Java并发包—锁机制(一)  >  2.Sync.FairSync.TryAcquire(公平锁) 我们直接来看代码 protected final boolean tryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState(); if (c == 0) { if (isFirst(current) && compareAndSetStat

java多线程(二)——锁机制synchronized(同步方法)

synchronized Java语言的关键字,可用来给对象和方法或者代码块加锁,当它锁定一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行这段代码.当两个并发线程访问同一个对象object中的这个加锁同步代码块时,一个时间内只能有一个线程得到执行.另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块.然而,当一个线程访问object的一个加锁代码块时,另一个线程仍然可以访问该object中的非加锁代码块. ——以上来源百度百科 一.方法内的变量为线程安全 “非线程安全”的问题

java多线程(三)——锁机制synchronized(同步语句块)

用关键字synchronized声明方法在某些情况下是有弊端的,比如A线程调用同步方法之行一个长时间的任务,那么B线程必须等待比较长的时间,在这样的情况下可以使用synchronized同步语句快来解决. 一.用同步代码块解决同步方法的弊端 Task类 1 package com.weishiyao.learn.day4.testSynchorized.ep2; 2 3 public class Task { 4 5 private String getData1; 6 private Stri

[java] java synchronized 关键字详解

Java语言的关键字,可用来给对象和方法或者代码块加锁,当它锁定一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行这段代码.当两个并发线程访问同一个对象object中的这个加锁同步代码块时,一个时间内只能有一个线程得到执行.另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块.然而,当一个线程访问object的一个加锁代码块时,另一个线程仍然可以访问该object中的非加锁代码块. 一.synchronized同步方法 1.synchronized 同步方法,为对象锁 publ

深入浅出 Java Concurrency (15): 锁机制 part 10 锁的一些其它问题[转]

主要谈谈锁的性能以及其它一些理论知识,内容主要的出处是<Java Concurrency in Practice>,结合自己的理解和实际应用对锁机制进行一个小小的总结. 首先需要强调的一点是:所有锁(包括内置锁和高级锁)都是有性能消耗的,也就是说在高并发的情况下,由于锁机制带来的上下文切换.资源同步等消耗是非常可观的.在某些极端情况下,线程在锁上的消耗可能比线程本身的消耗还要多.所以如果可能的话,在任何情况下都尽量少用锁,如果不可避免那么采用非阻塞算法是一个不错的解决方案,但是却也不是绝对的.

java synchronized类锁,对象锁详解(转载)

觉得还不错 留个记录,转载自http://zhh9106.iteye.com/blog/2151791 在java编程中,经常需要用到同步,而用得最多的也许是synchronized关键字了,下面看看这个关键字的用法. 因为synchronized关键字涉及到锁的概念,所以先来了解一些相关的锁知识. java的内置锁:每个java对象都可以用做一个实现同步的锁,这些锁成为内置锁.线程进入同步代码块或方法的时候会自动获得该锁,在退出同步代码块或方法时会释放该锁.获得内置锁的唯一途径就是进入这个锁的