标签: java-threads

Tomcat log4j2线程内存泄漏问题

我使用 log4j2 进行日志记录,tomcat8 和 java8 版本。我使用属性“monitorInterval”定期检查我的 log4j2.xml。在关闭我的 tomcat 期间,我面临内存泄漏问题。如何解决此内存泄漏问题?

以下是卡特琳娜日志:

2016 年 10 月 6 日 15:13:55.927 警告 [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads Web 应用程序 [mywebapp] 似乎启动了一个名为 [Log4j2-Log4j2Scheduled-1] 的线程,但是却未能阻止它。这很可能造成内存泄漏。线程的堆栈跟踪:sun.misc.Unsafe.park(本机方法) java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215) java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer. java:2078) java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1093) java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809) java.util.concurrent.ThreadPoolExecutor.getTask( ThreadPoolExecutor.java:1067) java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127) java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) java.lang.Thread.run(Thread.爪哇:745)

提前致谢。

更新:我分析了我的日志,实际上一旦 Log4jServletContextListener 被破坏,记录器上下文就会再次初始化。

2016-10-22 13:49:36,347 localhost-startStop-2 DEBUG Log4jServletContextListener 确保 Log4j 正确关闭。2016-10-22 13:49:36,382 localhost-startStop-2 调试启动 LoggerContext[name=bb4719, org.apache.logging.log4j.core.LoggerContext@d77214]...

实际上,在我的应用程序中,我在 web.xml 中使用 spring ContextLoaderListner,因此它可能在销毁 spring listner 时在内部使用日志记录。

谢谢

java log4j2 tomcat8 java-threads

7
推荐指数
1
解决办法
1万
查看次数

调试 Java 应用程序 IntelliJ 时挂起线程

我正在 IntelliJ 中调试多线程 Java 应用程序。我想在某个断点处挂起所有线程,并在单步执行代码时仅恢复选定的线程。我可以在断点处挂起所有线程,但是当我从一个线程单步执行代码时,其他线程也在运行。可以这样做吗?

先谢谢您的帮助!

java debugging multithreading intellij-idea java-threads

7
推荐指数
1
解决办法
1454
查看次数

检测您是在应用程序中的主进程还是远程服务进程

我有一个应用程序,它有一个在单独的进程中运行的远程服务:

<service android:name=".MyService" android:process=":remote"/>
Run Code Online (Sandbox Code Playgroud)

我也在使用 Application 类:

<application android:label="@string/app_name" android:name=".MyApplication" ...
Run Code Online (Sandbox Code Playgroud)

我可以做这样的事情吗?

public class MyApplication extends Application {

    public MyApplication() {
        if (isRemoteService()) {
            setupLog("remoteservice.log");
        } else {
            setupLog("application.log");
        }
    }
Run Code Online (Sandbox Code Playgroud)

我想我可以获取进程名称并使用它来检测我是否在远程服务或主应用程序中,但我还没有找到如何获取进程名称。我可以从 获取 PID android.os.Process.myPID(),但这对我没有多大帮助。

java service android process java-threads

6
推荐指数
2
解决办法
4310
查看次数

在Java中创建太多线程

我在我的Java应用程序中使用线程来并行获取数据(使用网络调用).我有一个方法(不在线程类中),它创建一个给定大小(最大10-15)的线程池并将它们用于网络调用,我从循环中多次调用该方法.

当我在慢速机器(3 GB RAM,Pentium-IV)上运行此应用程序时,一切正常,但是当我在iMac(32 GB RAM,i7处理器)上运行它时,它创建了太多线程,大约2,500个有时会抛出一个内存不足的错误.

我怀疑JVM在完成后不会将完成的线程重新放回池中,因此它正在创建新线程.

甚至在iMac上,如果我保留Thread.sleep(1000); 在for我上面提到的循环中一切正常.虽然创建了大约900个线程.

以下是此应用程序的代码示例:

public ArrayList<String> getValuesForKeyFromMaps(String key, ArrayList<Meta> locations) throws InterruptedException, ExecutionException {

    int threadNum = locations.size(); // 10-15 at max

    ExecutorService executor = Executors.newFixedThreadPool(threadNum);
    List<FutureTask<ArrayList<String>>> taskList = new ArrayList<FutureTask<ArrayList<String>>>();

    for(final Meta location : locations){

        FutureTask<ArrayList<String>> futureTask_1 = new FutureTask<ArrayList<String>>(new Callable<ArrayList<String>>() {
            public ArrayList<String> call() throws Exception {
                // Service call
                return getValues(key, location);
            }
        });
        taskList.add(futureTask_1);
        executor.execute(futureTask_1);

    }

    ArrayList<String> values = new ArrayList<String>();

    // Wait until all results …
Run Code Online (Sandbox Code Playgroud)

java multithreading out-of-memory executorservice java-threads

6
推荐指数
1
解决办法
4412
查看次数

在线程之间划分不均匀的数字

我只是学习Java中的Threads,我想按字母顺序排列单词列表.我的程序读取txt文件的文字并将它们放在一个String-array中.用户可以选择他们想要自己使用的线程数.我希望将数组拆分为偶数(尽可能)的线程,线程可以自己排序.

所以对我的问题:

如何在线程中尽可能地分割array.length?我的想法是空白,我想不出一个聪明的方法来做到这一点.

例如:如果我有一个22和4个线程的array.length,在这种情况下如何给出线程; 6,6,5和5个大小的阵列?需要适用于给出的每个号码.

我尽力解释它,请问是否有些不清楚!谢谢!

java arrays algorithm multithreading java-threads

6
推荐指数
2
解决办法
3255
查看次数

哪个线程会通知唤醒?

想象一下,我有3个线程有一个等待条件,第四个线程有一个通知条件.

现在,所有3个等待线程都运行并进入等待状态.完成后,第4个线程运行并调用notify一次.

通知如何确定唤醒哪个线程?它是调用等待第一个线程的线程,最后调用wait的线程,还是基于其他一些条件?

假设wait和notify使用相同的锁.

java synchronization java-threads

6
推荐指数
1
解决办法
1070
查看次数

具有corePoolSize 0的ThreadPoolExecutor在任务队列已满之前不应执行任务

我正在经历Java Concurrency In Practice并且陷入8.3.1线程创建和拆解主题.以下脚注警告要保持corePoolSize零.

开发人员有时会试图将核心大小设置为零,这样工作线程最终会被拆除,因此不会阻止JVM退出,但这可能会导致在不使用a的线程池中出现一些看似奇怪的行为.用于工作队列的SynchronousQueue(如newCachedThreadPool所做的那样).如果池已经是核心大小,则ThreadPoolExecutor仅在工作队列已满时才创建新线程.因此,在队列填满之前,提交给具有任何容量和核心大小为零的工作队列的线程池的任务将不会执行,这通常不是所希望的.

所以为了验证这一点,我写了这个程序,它不能像上面说的那样工作.

    final int corePoolSize = 0;
    ThreadPoolExecutor tp = new ThreadPoolExecutor(corePoolSize, 1, 5, TimeUnit.SECONDS,
            new LinkedBlockingQueue<>());

    // If the pool is already at the core size
    if (tp.getPoolSize() == corePoolSize) {
        ExecutorService ex = tp;

        // So tasks submitted to a thread pool with a work queue that has any capacity
        // and a core size of zero will not execute until the queue fills …
Run Code Online (Sandbox Code Playgroud)

java concurrency multithreading threadpool java-threads

6
推荐指数
1
解决办法
1169
查看次数

java中定时等待结束后线程未唤醒

我正在研究java中的等待(长时间超时),在官方文档中我发现了以下描述:

  • 其他某个线程调用该对象的notify方法,而线程T恰好被任意选择为要唤醒的线程。
  • 其他一些线程调用该对象的notifyAll 方法。
  • 其他一些线程中断线程 T。
  • 或多或少已经过了指定的实时时间。然而,如果超时为零,则不考虑实时性,线程只是等待直到收到通知。

最后一项说The specified amount of real time has elapsed, more or less,所以在我的选择中,如果我们调用wait(time),当时间流逝时,线程应该唤醒自己。

所以我写了下面的代码进行测试。

public static void testTimedWait() {
    Object lock = new Object();
    DateTimeFormatter df = DateTimeFormatter.ofPattern("HH:mm:ss:SSS");
    new Thread(() -> {
        synchronized (lock) {
            try {
                System.out.println(LocalTime.now().format(df) + "\t" + Thread.currentThread().getName() + " start to run");
                lock.wait(5_000);
                System.out.println(LocalTime.now().format(df) + "\t" + Thread.currentThread().getName() + " finished running");
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        } …
Run Code Online (Sandbox Code Playgroud)

java java-threads

6
推荐指数
1
解决办法
282
查看次数

在notifyAll()之前未被线程锁定的同步对象

我想有一个布尔值来通知系统某些特定服务启动的部分.

由于一些奇怪的原因,我收到了错误java.lang.IllegalMonitorStateException: object not locked by thread before notifyAll().

奇怪的是,notifyAll()位于一个synchronized块内,该块控制我调用notifyAll()的对象.

我的班级开头是这样的:

public class MyService {

    public static Boolean notifier = Boolean.valueOf(false);

    @Override
    public void start() {
        synchronized (MyService.notifier) {
            MyService.notifier = Boolean.valueOf(true);
            MyService.notifier.notifyAll();
        }
    }

    @Override
    public void stop() {
        synchronized (MyService.notifier) {
            MyService.notifier = Boolean.valueOf(false);
            MyService.notifier.notifyAll();
        }
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

我正在研究一个Android应用程序.我认为它不应该影响任何事情,但是如果影响java的工作方式,我会用该注释补充问题.

如果对象锁定在同步块中,为什么会出现异常?

java multithreading synchronization synchronized java-threads

5
推荐指数
1
解决办法
9669
查看次数

在java中执行新创建的线程的顺序是什么

class Test {
    boolean isFirstThread = true;

    private synchronized void printer(int threadNo) {
        if(isFirstThread) {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        isFirstThread = false;
        System.out.println(threadNo);
   }

   public void starter() {
        new Thread(){
            @Override()
            public void run() {
                printer(0);
            }
        }.start();

        new Thread(){
            @Override()
            public void run() {
                printer(1);
            }
        }.start();

        new Thread(){
            @Override()
            public void run() {
                printer(2);
            }
        }.start();

        new Thread(){
            @Override()
            public void run() {
                printer(3);
            }
        }.start();
    }
}
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,当我从main调用starter时.我创建了四个新的线程来调用同步函数.我知道无法预测线程的执行顺序.除非它们都等待一段时间,否则第一个线程可以完成并从同步块中退出.在这种情况下,我希望所有线程都保持在一个队列,所以我希望答案为
0
1 …

java multithreading java-threads

5
推荐指数
1
解决办法
91
查看次数