`

关于synchronized一个字符串的问题

    博客分类:
  • java
 
阅读更多

在memcached中我们公司首先根据查询条件获得key,然后查询mem有没有,如果没有将要进行数据库查询,然后add到memecached中,但是如果第一次同一时间大量访问这个key那么同一时间都要访问mysql造成mysql压力巨大,解决方法:

public void method(){

String key = String.valueOf(cityId);

。。。。

synchronized (key) {

。。。

}

}

想不明白key是方法的局部变量,怎么会同步呢,所以写了个测试类

package goodcenter.study;

 

import java.io.IOException;

 

public class TestSyString {

public void test(String str) throws InterruptedException{

String name = str;

synchronized(name){

Thread.sleep(5000);

System.out.println(name);

}

}

 

public static void main(String[] args) throws InterruptedException {

final TestSyString ts = new TestSyString();

Thread thread1 = new Thread(new Runnable() {

 

@Override

public void run() {

try {

ts.test("name");

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

});

Thread thread2 = new Thread(new Runnable() {

 

@Override

public void run() {

try {

ts.test("name");

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

});

thread1.start();

thread2.start();

Thread thread3 = new Thread(new Runnable() {

 

@Override

public void run() {

try {

Thread.sleep(1000);

String str = "name";

synchronized (str) {

System.out.println(str);

}

 

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

});

thread3.start();

Thread.sleep(6000);

String str = "name";

// System.out.println(str);

try {

System.in.read();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

 

}

结果可以看到,居然thread3由于thread1或thread2同步阻塞了,为什么嗯

经过查询才知道,因为JVM有一种优化机制,因为String类型的对象是不可变的,因此当你使用""的形式引用字符串时,如果JVM发现内存已经有一个这样的对象,那么它就使用那个对象而不再生成一个新的String对象,这样是为了减小内存的使用,所以同步阻塞

 

分享到:
评论

相关推荐

    java 创建字符串缓存类

    为了解决这个问题,我们可以自定义一个字符串缓冲类来存储和复用字符串,以提高效率。 首先,我们需要理解Java中的`StringBuffer`和`StringBuilder`类。这两个类都是线程安全和非线程安全的动态字符序列,分别在多...

    字符串过滤工具类,不错的类

    首先,字符串过滤工具类通常包含一系列静态方法或实例方法,这些方法可以接受一个字符串作为输入,然后根据预定义的关键字列表进行操作。关键字过滤可能包括但不限于删除、替换或标记含有特定关键字的字符串部分。 ...

    七种java字符串拼接详解.docx

    该方法接受一个字符串参数,并返回一个新的字符串对象,该对象是由原字符串和新字符串拼接而成的结果。 ```java String s1 = "沉默"; String s2 = "王二"; String result = s1.concat(s2); ``` `concat`方法在内部...

    Java字符串连接原理

    我们都知道,在Java中字符串可以用+连接,也可以使用StringBuilder或StringBuffer连接。 String str = abc+xyz; 那么这几种方式由什么区别呢。当然你可能会知道以下几点 String是只读字符串,String引用的字符串...

    Java实现产生随机字符串主键的UUID工具类

    在UUIDUtil类中,我们使用了一个私有静态变量instance来存储唯一的实例,并提供了一个getInstance()方法来获取该实例。同时,我们还提供了一些保护方法来格式化整数和短整数为十六进制字符串。 在generate()方法中...

    JAVA多线程实验报告

    实验主要分为两个部分:滚动字符串和蓝色反弹球。以下是对这些知识点的详细说明: 1. **线程的生命周期与状态迁移**: 线程具有不同的生命周期状态,包括新建(New)、就绪(Runnable)、运行(Running)、等待/...

    java课件,包括类与对象,数组,字符串,线程等

    这个压缩包包含了一系列关于Java基础知识的课件,涵盖了类与对象、数组、字符串、线程与同步等多个关键概念,适合初学者或复习者使用。 1. **类与对象**: 类是Java中的基本构造单元,它定义了对象的状态(数据...

    Java基础面试.pdf

    文件中提到了一个用例,即如何替换字符串中特定位置的字符,比如使用str.replace(5,'T')将"helloWorld"中的第五个字符替换为'T'。 接着,面试者可能还会被问及关于方法重载(Overloading)和重写(Overriding)的...

    java面试题目

    5. **Excel列编号**:这是一个进制转换问题,需要理解26进制(基于字母表顺序)的转换算法。 6. **线程与并发**: - 打印ABC:涉及线程同步和控制,可能用到Thread.sleep()、synchronized关键字等。 - 生产者消费...

    Lintcode-java版本

    - Reverse Vowels of a String(字符串中元音字母的反转):一个涉及字符串处理的有趣问题。 - Palindrome Permutation(回文排列):确定一个字符串是否可以重新排列成回文。 - Isomorphic Strings(同构字符串):...

    Java并发 synchronized锁住的内容解析

    在上面的示例代码中,我们创建了两个线程分别去add字符串"a"和字符串"b",然后使用synchronized关键字将addNum方法锁住,使得其他线程访问该方法时阻塞,从而解决了线程安全问题。 通过使用synchronized关键字,...

    Java基础面试.docx

    - `replace()`:将字符串中指定字符或子串替换为另一个字符或子串。 - `hashCode()`:返回字符串的哈希值,用于散列存储和比较。 - `substring()`:从指定位置开始截取到字符串的指定结束位置。 - `equals()`:...

    java基础知识面试题

    在创建字符串时 JVM 会首先检查字符串常量池,如果该字符串已经存在池中,则返回它的引用,如果不存在,则实例化一个字符串放到池中,并返回其引用。 四、String 是否不可变 String 中的内容不可变。一旦在常量池...

    蓝桥杯2014年校内选拔赛试题

    这个压缩包包含了Java本科组的试题,对于准备参加此类竞赛或希望提升Java编程技能的学生来说,是一份宝贵的学习资源。 在这个"Java本科A"的文件中,我们可以预见到一系列与Java编程相关的题目。这些题目可能涵盖...

    JavaScript关键字保留字属性及说明.docx

    JavaScript 关键字保留字属性及说明 JavaScript 中的关键字是指 JavaScript 语言...regexp 匹配的第一个字符串的起始位置、split() 将一个字符串用分隔符 separator 分割为假设干个字符串,然后将结果作为字符串返回。

    java 常见面试题.pdf

    在执行new操作时,JVM首先会在堆上分配一个String对象,并存储字符串"abc"。接着,字符串"abc"字面量存储在字符串常量池中。如果常量池之前没有创建"abc"的实例,new操作还会创建一个额外的String实例,并将其引用...

    String StringBuffer和StringBuilder区别之源码解析

    StringBuffer类是Java中另一种字符串类,它的字符串可以被修改。StringBuffer类是线程安全的,所有的方法都加上了synchronized关键字,保证了线程安全性。 在StringBuffer类的源码中,我们可以看到,它的扩容机制是...

    125个关于java的问题集锦

    3. **字符串分隔函数**:题目中的函数`split(String str, int chars)`将字符串按指定字符长度分隔,返回一个字符串数组。这个函数在处理大量文本或需要定制分割逻辑时很有用。 4. **Java与JavaScript的区别**: - ...

    Java程序设计-孙晨霞ppt

    5. **字符串处理**:Java中的String类,字符串常量池,以及StringBuilder和StringBuffer的使用。 6. **异常处理**:异常的分类,try-catch-finally结构,以及自定义异常的创建和处理。 7. **输入/输出流**:I/O流...

    3160104875_杨樾人_homework31

    这种设计提供了缓存优势,因为相同的字符串值可以共享同一个对象,即字符串池。此外,由于不可变性,String对象可以在多线程环境下安全地使用,无需担心数据同步问题。 1.2 StringBuilder源码分析 StringBuilder类...

Global site tag (gtag.js) - Google Analytics