精华内容
下载资源
问答
  • 常量池以及多线程

    2019-03-01 13:28:41
    常量池: 1:常量: final修饰的成员变量表示常量,值一旦给定就无法改变 final修饰的变量有三种:静态变量、实例变量和局部变量,分别表示三种类型的常量 2:静态常量池和运行时常量池: 静态常量池:即*....

    常量池:

     1:常量:

    final修饰的成员变量表示常量,值一旦给定就无法改变

    final修饰的变量有三种:静态变量、实例变量和局部变量,分别表示三种类型的常量

    2:静态常量池运行时常量池:

     静态常量池:即*.class文件中的常量池,class文件中的常量池不仅仅包含字符串(数字)字面量,还包含类、方法的信息,占用class文件绝大部分空间。

    运行时常量池:则是jvm虚拟机在完成类装载操作后,将class文件中的常量池载入到内存中,并保存在方法区中,我们常说的常量池,就是指方法区中的运行时常量池。

    优点:

    常量池是为了避免频繁的创建和销毁对象而影响系统性能,其实现了对象的共享。例如字符串常量池,在编译阶段就把所有的字符串文字放到一个常量池中。

    节省内存空间:常量池中所有相同的字符串常量被合并,只占用一个空间。

    节省运行时间:比较字符串时,==比equals()快。对于两个引用变量,只用==判断引用是否相等,也就可以判断实际值是否相等。

    线程池:

    java提供的四种线程池:

    1. newSingleThreadExecutor:

    创建一个单线程的线程池。这个线程池只有一个线程在工作。一个线程池中只能跑一个线程,单线程串行执行任务,但一个任务完成后才能进行下一个任务。

    2.newFixedThreadPool:

    可以规定线程池的大小,小于这个数量就创建新线程。当达到这个数量,就只能有这些线程,别的任务等待运行的任务结束再使用线程。

    3. newCachedThreadPool(推荐用这个):

    线程池的大小是根据jvm的大小而定的。当线程池的大小(核心线程池大小就是创建线程池的时候默认创建几个线程)大于正在执行的任务的数量的时候,会去自动释放那些空闲的线程,当任务增加,回去新添加线程。

    4.newScheduledThreadPool:

    支持任务调度的线程池。

    优点:

    可以并行的执行多个线程,提高效率。这里的提高效率,不是说提高系统的性能,而是每个线程都有相应的带宽,多线程就是充分利用cpu资源。

    一般功能较复杂(用户注册,其他的操作放到多线程中,不然用户体验很不好)或者需要轮询操作的方法用到多线程。

    多线程:

    一:继承Thread类:

    启动:

    1:重写run方法,run方法的方法体表示线程要执行的操作

    2:创建Thread类的实例

    3:通过调用线程对象的start方法来启动线程

    currentThread:Thread类的静态方法,返回当前正在执行的线程对象

    getName:Thread类的实例方法,返回当前线程的名称。

    (用继承Thread类的方法来创建线程类时,多个线程之间无法共享线程类的实例)

    二:实现Runnable接口:

    1:重新Runnable接口的run方法

    2:创建Runnable接口实现类的对象

    3:调用线程对象的statrt方法

    三:实现callable接口:

     

    Runnable和Callable的区别

    1:Runnable执行方法是run(),Callable是call()

    2:实现Runnable接口的任务线程无返回值;实现Callable接口的任务线程能返回执行结果

    3:call方法可以抛出异常,run方法若有异常只能在内部消化

    多线程的生命周期:(启动线程用start方法,而不是run方法)

    新建和就绪状态:(调用完Start方法就进入就绪状态)

    运行和阻塞状态:

    阻塞状态:

    1:调用Sleep方法,主动放弃所占用的处理器资源。

    2:调用一个阻塞式I/O方法,在方法返回前,线程处于阻塞状态。

    3:线程在等待一个通知

    4:程序调用线程时的suspend方法,将线程挂起(但是容易造成死锁)

    解除阻塞状态:

    1:sleep方法过了指定时间

    2:线程调用的I/O方法已返回

    3:线程接收到通知

    4:对挂起状态的线程调用resume恢复方法。

    线程死亡:

    run或call方法执行完成,线程结束

    线程抛出一个为捕获的异常

    直接调用该线程的Stop方法结束线程(容易死锁,不推荐)

    (不用对一个死亡的线程使用start方法,使它重新启动)

    IsAlive

    就绪,运行,阻塞:

    True

    新建,死亡:

    Flase

    Join让一个线程等待另一个线程完成的方法。

    守护线程:Gc处理机制:所以前台线程死亡,后台线程自动死亡

    Thread的静态类:

    线程睡眠:sleep:进入阻塞状态,睡眠时间内,不会获得执行的机会,可以用来暂停线程

    线程让步:YieId:进入就绪状态,让政治执行的线程暂停,让它不会阻塞线程。

    (调用YieId方法暂停后,只有优先级与当前线程相同或者更高的处于就绪状态的线程会获得执行的机会)

    join和YieId的区别:

    Sleep()

    YieId()

    sleep暂停当前线程后,后给其他线程执行机会,不理会线程优先级

    YieId只会让优先级相同或更高的获得执行机会

     

    sleep会将线程转入阻塞状态,经过阻塞时间后进入就绪状态。

     

    Yie会强制当前线程进入就绪状态,因此完全又可以让其他线程直接调用

     

    sleep要么捕获异常,要么声明异常

     

    YieId则没有声明就抛出任何异常

     

    可移植性高

    可移植性比sleep低

     

    同步锁(LOCK)

    死锁:俩个线程相互等待对方同时释放同步监视器,就会发生死锁。

     

    sleep:(不释放锁)

    wait:(释放锁)当前线程等待,知道其他线程调用notify,notifyAll来唤醒

    notify:获取单个线程

    notifyAll:获取多个线程)

     

     

    展开全文
  • 主要介绍了浅谈Java多线程编程中Boolean常量的同步问题,主要针对线程之间同步了不同的布尔对象的问题,需要的朋友可以参考下
  • 在JAVA中通过synchronized语句可以实现多线程并发。使用同步代码块,JVM保证同一时间只有一个线程可以拥有某一对象的锁。锁机制实现了多个线程安全地对临界资源进行访问。同步代码写法如下:代码1:Object obj = new...

    在JAVA中通过synchronized语句可以实现多线程并发。使用同步代码块,JVM保证同一时间只有一个线程可以拥有某一对象的锁。锁机制实现了多个线程安全地对临界资源进行访问。

    同步代码写法如下:

    代码1:

    Object obj = new Object();

    ...

    synchronized(obj) {

    //TODO: 访问临界资源

    }

    JAVA的多线程总是充满陷阱,如果我们用Boolean作为被同步的对象,可能会出现以下两种情况:

    一. 以为对一个对象加锁,实际同步的是不同对象。

    代码2:

    private volatile Boolean isTrue = false;

    publich void aMethod() {

    ...

    synchronized(isTrue) {

    isTrue = !isTrue;

    //TODO: 访问临界资源

    isTrue = !isTrue;

    }

    ...

    }

    咋一看上面的代码没有问题,由于使用了synchronized(isTrue)同一时间只能有一个线程访问临界资源,但事实并不是这样。因为false和true这两个常量对应着两个不同的对象。当isTrue产生变化时,很可能导致不同的线程同步了不同的对象。JAVA的自动装箱会将false变为Boolean.FALSE,将true变为Boolean.TRUE(同时这也说明了此处若将false改为Boolean.FALSE其结果也是一样的)。写一个以上情况的测试代码如下:

    代码3:

    public class BooleanTest {

    private volatile Boolean isTrue = Boolean.FALSE; //此处用false也一样

    public void aMethod() {

    for(int i=0;i<10;i++) {

    Thread t = new Thread() {

    public void run() {

    synchronized(isTrue) {

    isTrue = !isTrue;

    System.out.println(Thread.currentThread().getName() + " - isTrue=" + isTrue);

    try{

    Double ran = 1000 * Math.random();

    Thread.sleep(ran.intValue());

    }catch(InterruptedException e) {}

    if(!isTrue) System.out.println(Thread.currentThread().getName() + " - Oh, No!");

    isTrue = !isTrue;

    }

    }

    };

    t.start();

    }

    }

    public static void main(String... args) {

    BooleanTest bt = new BooleanTest();

    bt.aMethod();

    }

    }

    运行以上代码,不时的会看到 " - Oh, No!",表示不同的线程同时进入到synchronized代码块中。

    二. 以为同步的是不同对象,实际是一个对象。

    有时候我们可能希望在多个对象上进行同步,如果使用了Boolean作为被同步对象,很可能会导致本来应该没有关系的两个同步块使用了相同对象的锁。示例如下:

    代码4:

    private volatile Boolean aBoolean = Boolean.FALSE;

    private volatile Boolean anotherBoolean = false;

    public void aMethod() {

    ...

    synchronized(aBoolean) {

    //TODO: 访问临界资源1

    }

    ...

    }

    public void anotherMethod() {

    ...

    synchronized(anotherBoolean) {

    //TODO: 访问临界资源2

    }

    ...

    }

    假设原本aMethod和anotherMethod分别会被两组没有关系的线程调用。但是由于Boolean.FALSE和false指向的是同一个对象,可能导致对临界资源2的访问被临界资源1阻塞了(反之亦然)。

    以上两种情况说明,在使用同步块时,尽量不用使用Boolean对象作为被同步对象,不然可能会出现意想不到的问题,或者对以后的代码修改造成陷阱。

    从此也可以看出,任何对常量的同步都是有风险的。如果一定要对 Boolean 进行同步,一定要用 new 操作符来创建 Boolean 对象。

    展开全文
  • 在java中通过synchronized语句可以实现多线程并发。使用同步代码块,jvm保证同一时间只有一个线程可以拥有某一对象的锁。锁机制实现了多个线程安全地对临界资源进行访问。同步代码写法如下:代码1:object obj = new...

    在java中通过synchronized语句可以实现多线程并发。使用同步代码块,jvm保证同一时间只有一个线程可以拥有某一对象的锁。锁机制实现了多个线程安全地对临界资源进行访问。

    同步代码写法如下:

    代码1:

    object obj = new object();

    ...

    synchronized(obj) {

    //todo: 访问临界资源

    }

    java的多线程总是充满陷阱,如果我们用boolean作为被同步的对象,可能会出现以下两种情况:

    一. 以为对一个对象加锁,实际同步的是不同对象。

    代码2:

    private volatile boolean istrue = false;

    publich void amethod() {

    ...

    synchronized(istrue) {

    istrue = !istrue;

    //todo: 访问临界资源

    istrue = !istrue;

    }

    ...

    }

    咋一看上面的代码没有问题,由于使用了synchronized(istrue)同一时间只能有一个线程访问临界资源,但事实并不是这样。因为false和true这两个常量对应着两个不同的对象。当istrue产生变化时,很可能导致不同的线程同步了不同的对象。java的自动装箱会将false变为boolean.false,将true变为boolean.true(同时这也说明了此处若将false改为boolean.false其结果也是一样的)。写一个以上情况的测试代码如下:

    代码3:

    public class booleantest {

    private volatile boolean istrue = boolean.false; //此处用false也一样

    public void amethod() {

    for(int i=0;i<10;i++) {

    thread t = new thread() {

    public void run() {

    synchronized(istrue) {

    istrue = !istrue;

    system.out.println(thread.currentthread().getname() + " - istrue=" + istrue);

    try{

    double ran = 1000 * math.random();

    thread.sleep(ran.intvalue());

    }catch(interruptedexception e) {}

    if(!istrue) system.out.println(thread.currentthread().getname() + " - oh, no!");

    istrue = !istrue;

    }

    }

    };

    t.start();

    }

    }

    public static void main(string... args) {

    booleantest bt = new booleantest();

    bt.amethod();

    }

    }

    运行以上代码,不时的会看到 " - oh, no!",表示不同的线程同时进入到synchronized代码块中。

    二. 以为同步的是不同对象,实际是一个对象。

    有时候我们可能希望在多个对象上进行同步,如果使用了boolean作为被同步对象,很可能会导致本来应该没有关系的两个同步块使用了相同对象的锁。示例如下:

    代码4:

    private volatile boolean aboolean = boolean.false;

    private volatile boolean anotherboolean = false;

    public void amethod() {

    ...

    synchronized(aboolean) {

    //todo: 访问临界资源1

    }

    ...

    }

    public void anothermethod() {

    ...

    synchronized(anotherboolean) {

    //todo: 访问临界资源2

    }

    ...

    }

    假设原本amethod和anothermethod分别会被两组没有关系的线程调用。但是由于boolean.false和false指向的是同一个对象,可能导致对临界资源2的访问被临界资源1阻塞了(反之亦然)。

    以上两种情况说明,在使用同步块时,尽量不用使用boolean对象作为被同步对象,不然可能会出现意想不到的问题,或者对以后的代码修改造成陷阱。

    从此也可以看出,任何对常量的同步都是有风险的。如果一定要对 boolean 进行同步,一定要用 new 操作符来创建 boolean 对象。

    希望与广大网友互动??

    点此进行留言吧!

    展开全文
  • Java多线程String的常量池特性

    千次阅读 2016-11-22 11:01:55
    在JVM中具有String常量池缓存的功能将...出现这样的情况是因为String的两个值都是AA,两个线程持有相同的锁,所以造成线程B不能执行。这就是String常量池所带来的问题。 这样实例化一个对象就持有两个不同的锁了。

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

    这里写图片描述

    将synchronized(string)同步块与String联合使用时,要注意常量池带来的一些例外。

    这里写图片描述
    这里写图片描述

    出现这样的情况是因为String的两个值都是AA,两个线程持有相同的锁,所以造成线程B不能执行。这就是String常量池所带来的问题。

    这里写图片描述
    这里写图片描述

    这样实例化一个对象就持有两个不同的锁了。

    展开全文
  • 在JAVA中通过synchronized语句可以实现多线程并发。使用同步代码块,JVM保证同一时间只有一个线程可以拥有某一对象的锁。锁机制实现了多个线程安全地对临界资源进行访问。 同步代码写法如下: 代码1: Java代码 ...
  • 在JVM中有string常量池缓存的功能。 package com.leran.thread.demo1; public class Test { public static void main(String[] args) { String a = "a"; String b = "a"; System.out.println(a == b); } } ...
  • 1.Boolean对象赋值为true和false,会改变指向的对象.测试代码:private volatile Boolean isTrue = Boolean.FALSE; //此处用false也一样public void aMethod() {for (int i = 0; i < 100; i++) {Thread t = new ...
  • 《Java多线程 - 不要同步Boolean常量》测试代码
  • 本文内容部分引自《Java多线程编程核心技术》,感谢作者!!! 代码地址:https://github.com/xianzhixianzhixian/thread.git 什么是常量池 这里单单只说Java常量池,Java中的常量池,实际上分为两种形态:静态...
  • 今天总结多线程,在自己写的一个多线程程序中,我想要线程处理客户类100次,但是这个 循环次数 应该定义在哪儿呢? 按理说应该定义在主函数中,便于修改,但是我把循环次数SUM定义在了主函数中后,在线程类中引用SUM...
  • 将synchronized(String)与String 混合使用时需要注意String的常量池特性带来的影响 package extthread; import service.Service; public class ThreadA extends Thread { private Service service; public ...
  • 通过共享对象通信忙等待wait(),notify()和 notifyAll()丢失的信号假唤醒多线程等待相同信号不要对常量字符串或全局对象调用 wait()通过共享对象通信线程间发送信号的一个简单方式是在共享对象的变量里设置信号值。...
  • String常量池:String常量池,是java为了保存字符串常量在方法区里开辟的一段空间,在执行如String str=”aa”;是会先检查常量池中有没有“aa”,如果有则直接让str指向常量池中的“aa”,如果没有则会新建一个“aa”...
  • 实质:操作系统的执行单元是进程(程序),每个jvm实例都是一个进程,系统中可以同时有多个jvm实例,也就是有多个java进程,每个jvm中可以有多个线程,它们共享方法区和堆内存,... 多线程:充分利用单个cpu,通过...
  • Java提供了java.lang.Thread.State类,它定义了线程状态的ENUM常量,如下所示:常量类型:NEW声明:public static final Thread.State NEW描述:尚未启动的线程线程状态。常量类型: Runnable声明:public static ...
  • 多线程

    2016-03-01 19:12:04
    (2) 学习多线程的目的:将耗时操作放到后台线程去执行。 (3) 通过耗时操作演练可知,操作效率的顺序: I/O操作 (4) 使用@””定义的字符串保存在常量区,使用stringWithFormat拼接的字符串保存在堆区。 (5) 网络...
  • 目录 1、Java内存模型 1.1、Java程序执行流程回顾 1.2、Java内存模型 ...2、多线程特性 2.1、原子性 2.2、可见性 2.3、有序性 3、多线程控制类 3.1、ThreadLocal 3.1.1、作用 3.1.2、示
  • 回顾一下,线程的五个状态: new:新生状态 runnable:java虚拟机中执行的线程所属的状态 blocked:被阻塞等待监视器锁定的...在java里面对应一个常量,下面看一下例子: package duoxiancheng; public class TestSta
  • 1.与线程相关的栈的问题 ...(1)定义:如果多线程环境下代码运行的结果符合单线程环境运行的结果,则说这个程序是线程安全的。 3.线程不安全的原因 (1)线程之间交错运行; (2) 没存区域的数据...
  • 本帖最后由 20408912 于 2017-4-3 18:04 编辑最近学了几个星期的python 一直在学习基础的变量 列表 循环之类的前几天看了一节课程 我也参照了一下 做出了python多线程图片爬虫在这里和大家一起学习探讨一下 求大神...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,633
精华内容 653
关键字:

多线程常量