2.2.10数据类型String的常量池特性

Posted 成功的路上总是离不开贵人的帮助,名师的指点和小人的刺激。

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2.2.10数据类型String的常量池特性相关的知识,希望对你有一定的参考价值。

在JVM中具有String常量池缓存的功能

package com.cky.test;

/**
 * Created by edison on 2017/12/8.
 */
public class Test {
    public static void main(String[] args) {
       String a= "a";
       String b= "a";
        System.out.println(a==b);

    }
}
true

将synchronized(string)同步代码块和String联合使用,结果出现意外

测试

package com.cky.bean;

/**
 * Created by edison on 2017/12/8.
 */
public class Service {

    public static  void print(String str) {
        try {
            synchronized (str) {
                while(true) {
                    System.out.println(Thread.currentThread().getName());
                    Thread.sleep(1000);
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }



}
package com.cky.thread;

import com.cky.bean.Service;

/**
 * Created by edison on 2017/12/8.
 */
public class ThreadA extends  Thread{
    private Service service;

    public ThreadA(Service service) {
        this.service = service;
    }

    @Override
    public void run() {
        super.run();
        service.print("AA");
    }
}
package com.cky.thread;

import com.cky.bean.Service;

/**
 * Created by edison on 2017/12/8.
 */
public class ThreadB extends  Thread{


    private Service service;

    public ThreadB(Service service) {
        this.service = service;
    }

    @Override
    public void run() {
        super.run();
        service.print("AA");
    }
}
package com.cky.test;

import com.cky.bean.Service;
import com.cky.thread.ThreadA;
import com.cky.thread.ThreadB;

/**
 * Created by edison on 2017/12/8.
 */
public class Test {
    public static void main(String[] args) {
        Service service = new Service();
        ThreadA threadA = new ThreadA(service);
        threadA.setName("a");
        threadA.start();
        ThreadB threadB = new ThreadB(service);
        threadB.setName("b");
        threadB.start();

    }
}
a
a
a
a
a
a
a
a

结果是无限循环的打印a

出现这种情况的原因是因为String的两个值都是AA,两个线程持有相同的锁。所以造成线程B不能执行,这就是String常量2池带来的问题,所以大多数情况下都不使用String做所对象,比如new Object实例化一个Object对象,但他不放入缓存中

测试

package com.cky.bean;

/**
 * Created by edison on 2017/12/8.
 */
public class Service {

    public static  void print(Object object) {
        try {
            synchronized (object) {
                while(true) {
                    System.out.println(Thread.currentThread().getName());
                    Thread.sleep(1000);
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }



}
package com.cky.thread;

import com.cky.bean.Service;

/**
 * Created by edison on 2017/12/8.
 */
public class ThreadA extends  Thread{
    private Service service;

    public ThreadA(Service service) {
        this.service = service;
    }

    @Override
    public void run() {
        super.run();
        service.print(new Object());
    }
}
package com.cky.thread;

import com.cky.bean.Service;

/**
 * Created by edison on 2017/12/8.
 */
public class ThreadB extends  Thread{


    private Service service;

    public ThreadB(Service service) {
        this.service = service;
    }

    @Override
    public void run() {
        super.run();
        service.print(new Object());
    }
}
package com.cky.test;

import com.cky.bean.Service;
import com.cky.thread.ThreadA;
import com.cky.thread.ThreadB;

/**
 * Created by edison on 2017/12/8.
 */
public class Test {
    public static void main(String[] args) {
        Service service = new Service();
        ThreadA threadA = new ThreadA(service);
        threadA.setName("a");
        threadA.start();
        ThreadB threadB = new ThreadB(service);
        threadB.setName("b");
        threadB.start();

    }
}
a
b
b
a
a
b
a
b
b
a

交替打印说明一个一个对象锁

以上是关于2.2.10数据类型String的常量池特性的主要内容,如果未能解决你的问题,请参考以下文章

String数据类型的数据存储在哪里?

Java基础2:基本数据类型与常量池

string 是啥类型的?

关于intern的一切

String常用特性分析

测试常量池