Java中一个线程执行死循环有什么后果

假设有两个线程在并发运行,一个线程执行的代码中含有一个死循环如:while(true)....当该线程在执行while(true)中代码时,另一个线程会有机会执行吗?

示例代码(代码来源于互联网)

public class Service {
  Object object1 = new Object();

  public void methodA() {
    synchronized (object1) {
      System.out.println("methodA begin");
      boolean isContinueRun = true;
      //在这里执行一个死循环
      while (isContinueRun) {

      }
      System.out.println("methodA end");
    }
  }

  Object object2 = new Object();

  public void methodB() {
    synchronized (object2) {
      System.out.println("methodB begin");
      System.out.println("methodB end");
    }
  }
}

两个线程类的实现如下:

import service.Service;

public class ThreadA extends Thread {

  private Service service;

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

  @Override
  public void run() {
    service.methodA();
  }

}

线程A执行methodA(),methodA()中有一个死循环

import service.Service;

public class ThreadB extends Thread {

  private Service service;

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

  @Override
  public void run() {
    service.methodB();
  }

}

线程B执行methodB(),当线程A进入methodA()中的while死循环时,线程B的能不能执行完成?

测试类

import service.Service;
import extthread.ThreadA;
import extthread.ThreadB;

public class Run {

  public static void main(String[] args) {
    Service service = new Service();

    ThreadA athread = new ThreadA(service);
    athread.start();

    ThreadB bthread = new ThreadB(service);
    bthread.start();
  }

}

由于线程A和线程B获得的对象锁不是同一把锁,从结果中可以看出,线程B是可以执行完成的。而线程A由于进入了while死循环,故线程A一直执行运行下去了(整个程序未结束),但线程B会结束。

也就是说,尽管线程A一直在while中执行,需要占用CPU。但是,线程的调度是由JVM或者说是操作系统来负责的,并不是说线程A一直在while循环,然后线程B就占用不到CPU了。对于线程A而言,它就相当于一个“计算密集型”作业了。如果我们的while循环是不断地测试某个条件是否成立,那么这种方式就很浪费CPU,可参考一个具体的实例:JAVA多线程之线程间的通信方式 中的“线程间的通信方式”第二点while轮询。

如果把Service.java修改成如下:

public class Service {
//  Object object1 = new Object();

  public void methodA() {
    synchronized (this) {
      System.out.println("methodA begin");
      boolean isContinueRun = true;
      //在这里执行一个死循环
      while (isContinueRun) {

      }
      System.out.println("methodA end");
    }
  }

//  Object object2 = new Object();

  public void methodB() {
    synchronized (this) {
      System.out.println("methodB begin");
      System.out.println("methodB end");
    }
  }
}

若线程A先获得对象锁时,由于while循环,线程A一直在while空循环中。而线程B也因为无法获得锁而执行不了methodB()。

可以看出,如果在一个线程在synchronized方法中无法退出,无法将锁释放,另一个线程就只能无限等待了。

以上就是本文的全部内容,希望对大家学习java多线程有所帮助。

(0)

相关推荐

  • 基于Java HashMap的死循环的启示详解

    一.单线程改造为多线程也是个技术活 正如我们看到耗子叔叔博客里写的那样,原来是单线程的应用程序,"后来,我们的程序性能有问题,所以需要变成多线程的,于是,变成多线程后到了线上,发现程序经常占了100%的CPU". 考虑到是淘宝的工程师曝出来的问题,他们的技术基础一般都很扎实,连他们都用错了,所以把单线程改造为多线程并不是想象中的那么简单,我认为. 你可能很不服气地反问,淘宝的工程师又怎么了,单线程改为多线程有什么难的?无非就是应用现有的多线程技术嘛,你看,我有非常强烈的线程安全意识,我

  • Java并发之不可思议的死循环详解

    下面的代码将发生死循环: package com.zzj.concurrency; public class VolatileObjectTest implements Runnable{ private ObjectA objectA; // 加上volatile 就可以正常结束While循环了 public VolatileObjectTest(ObjectA a) { this.objectA = a; } public ObjectA getA() { return objectA; }

  • Java中一个for语句导致无穷大死循环的例子

    在Java开发中常用到For循环,它对简化业务处理,提高效率,非常有帮助.但要防止程序算法中可能导致死循环的情况,而且有的死循环还不好察觉.比如下面这个例子,算法极容易认为是50,实际上是无穷大的一个死循环. public class CycTest { /** * @param args the command line arguments */ public static void main(String[] args) { int end = Integer.MAX_VALUE; //定义

  • Java中一个线程执行死循环有什么后果

    假设有两个线程在并发运行,一个线程执行的代码中含有一个死循环如:while(true)....当该线程在执行while(true)中代码时,另一个线程会有机会执行吗? 示例代码(代码来源于互联网) public class Service { Object object1 = new Object(); public void methodA() { synchronized (object1) { System.out.println("methodA begin"); boolea

  • Java中保证线程顺序执行的操作代码

    只要了解过多线程,我们就知道线程开始的顺序跟执行的顺序是不一样的.如果只是创建三个线程然后执行,最后的执行顺序是不可预期的.这是因为在创建完线程之后,线程执行的开始时间取决于CPU何时分配时间片,线程可以看成是相对于的主线程的一个异步操作. public class FIFOThreadExample { public synchronized static void foo(String name) { System.out.print(name); } public static void

  • java排查一个线上死循环cpu暴涨的过程分析

    问题,打一个页面cpu暴涨,打开一次就涨100%,一会系统就卡的不行了. 排查方法,因为是线上的linux,没有用jvm监控工具rim链接上去. 只好用命令排查: top cpu排序,一个java进程cpu到500%了,什么鬼..... 查到对应java进程 jps || ps -aux | grep 端口 pid=13455 查看进程中线程使用情况 T排序 查看cpu占用time最高的线程编号 top -Hp 13455 有个线程9877 的时间一直在爆涨 获取线程十六进制地址9877 (十六

  • Java中守护线程介绍及使用

    目录 一.什么是守护线程 二.为什么需要守护线程 三.如何使用 注意: 总结 一.什么是守护线程 在说守护线程之前,我们先说一下什么是用户线程. 用户线程:我们平常创建的普通线程.守护线程(即 Daemon thread):是个服务线程,用来服务于用户线程:不需要上层逻辑介入,当然我们也可以手动创建一个守护线程.在JVM中,所有非守护线程都执行完毕后,无论有没有守护线程,虚拟机都会自动退出. 二.为什么需要守护线程 存在任意一个用户线程的时候,JVM就不会退出.那么JVM 程序在什么情况下能够正

  • Java中终止线程的方法详解

    Java中终止线程的方式主要有三种: 1.使用stop()方法,已被弃用.原因是:stop()是立即终止,会导致一些数据被到处理一部分就会被终止,而用户并不知道哪些数据被处理,哪些没有被处理,产生了不完整的"残疾"数据,不符合完整性,所以被废弃.So, forget it! 2.使用volatile标志位 看一个简单的例子: 首先,实现一个Runnable接口,在其中定义volatile标志位,在run()方法中使用标志位控制程序运行 public class MyRunnable i

  • 完美解决Java中的线程安全问题

    给出一个问题,如下: 解决方案如下: public class Demo_5 { public static void main(String[] args) { //创建一个窗口 TicketWindow tw1=new TicketWindow(); //使用三个线程同时启动 Thread t1=new Thread(tw1); Thread t2=new Thread(tw1); Thread t3=new Thread(tw1); t1.start(); t2.start(); t3.s

  • Java中的线程同步与ThreadLocal无锁化线程封闭实现

    Synchronized关键字 Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行.另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块. 然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(

  • Java中启动线程start和run的两种方法

    一.区别 Java中启动线程有两种方法,继承Thread类和实现Runnable接口,由于Java无法实现多重继承,所以一般通过实现Runnable接口来创建线程.但是无论哪种方法都可以通过start()和run()方法来启动线程,下面就来介绍一下他们的区别. start方法: 通过该方法启动线程的同时也创建了一个线程,真正实现了多线程.无需等待run()方法中的代码执行完毕,就可以接着执行下面的代码.此时start()的这个线程处于就绪状态,当得到CPU的时间片后就会执行其中的run()方法.

  • Java中后台线程实例解析

    本文研究的主要是Java中后台线程的相关问题,具体介绍如下. 以前从来没有听说过,java中有后台线程这种东西.一般来说,JVM(JAVA虚拟机)中一般会包括俩种线程,分别是用户线程和后台线程.所谓后台线程(daemon)线程指的是:在程序运行的时候在后台提供的一种通用的服务的线程,并且这种线程并不属于程序中不可或缺的部分.因此,当所有的非后台线程结束的时候,也就是用户线程都结束的时候,程序也就终止了.同时,会杀死进程中的所有的后台线程.反过来说,只要有任何非后台线程还在运行,程序就不会结束.不

  • 详解Java中的线程池

    1.简介 使用线程池可以避免线程的频繁创建以及销毁. JAVA中提供的用于实现线程池的API: Executor.ExecutorService.AbstractExecutorService.ThreadPoolExecutor.ForkJoinPool都位于java.util.concurrent包下. *ThreadPoolExecutor.ForkJoinPool为线程池的实现类. 2.Executor public interface Executor { /** * 向线程池提交一个

随机推荐