信号量和线程问题

发布于 2024-12-22 13:43:50 字数 1131 浏览 3 评论 0原文

在阅读了关于信号量的内容后,我尝试了这个测试代码,其中创建了两个线程 A 和 B。我的目标是,让线程 A 等待 10 秒,以便线程 B 中的某些操作完成。但是当我稍微改变了线程B中的逻辑,通过引入一个永远不会出来的无限while循环时,线程A也挂起了,程序永远运行。有人可以帮助我如何实现我正在寻找的目标吗?

包包;

import java.util.concurrent.Semaphore;

public class Concurrency {
    public int count = 0;

  public static void main(String args[]) throws Exception {
    final Semaphore sem = new Semaphore(1, true);
    Thread thrdA, thrdB;
    thrdA = new Thread(new Runnable() {
        @Override
        public void run() {
            synchronized (sem) {
                try {
                    sem.wait(10000);
                    System.out.println("thread1");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        }
    });
    thrdB = new Thread(new Runnable() {
        @Override
        public void run() {
            synchronized (sem) {
                System.out.println("thread2");

                while(true){

                }
            }

        }
    });

    thrdA.start();
    thrdB.start();

    thrdA.join();
    thrdB.join();

  }
}

After reading about semaphores I tried this test code in which I create two threads A and B. My aim is, let thread A wait for 10 secs for some operation in Thread B to complete. But as I changed the logic in thread B a little , by introducing an infinite while loop which never comes out , the Thread A is also hanging, and the program runs forever. Can anybody help me how to achieve the goal which I am looking for?

package pack;

import java.util.concurrent.Semaphore;

public class Concurrency {
    public int count = 0;

  public static void main(String args[]) throws Exception {
    final Semaphore sem = new Semaphore(1, true);
    Thread thrdA, thrdB;
    thrdA = new Thread(new Runnable() {
        @Override
        public void run() {
            synchronized (sem) {
                try {
                    sem.wait(10000);
                    System.out.println("thread1");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        }
    });
    thrdB = new Thread(new Runnable() {
        @Override
        public void run() {
            synchronized (sem) {
                System.out.println("thread2");

                while(true){

                }
            }

        }
    });

    thrdA.start();
    thrdB.start();

    thrdA.join();
    thrdB.join();

  }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

蓝天白云 2024-12-29 13:43:50

您的代码中有很多问题。

  1. 正如评论和答案中提到的,如果您想要等待/通知,则不必使用Semaphore
  2. while(true) 会给 CPU 带来沉重的负载。考虑使用 Thread.sleep 或获取信号量/锁。
  3. 您需要详细说明您想要实现的目标。如果您希望 threadB 等待 threadA,则不需要任何信号量/锁。只需在 thread2.run 中执行任何其他调用之前调用 thread1.join() 即可。

There are many issues in your code.

  1. As mentioned in comments and answers, you if you want wait/notify you don't have to use Semaphore.
  2. while(true) puts heavy load to the CPU. Consider using Thread.sleep, or acquiring a semaphore/lock.
  3. You need to elaborate more about what you want to achieve. If you want the threadB wait for threadA you don't need any semaphore/lock. Just call thread1.join() before doing any other calls in thread2.run.
只等公子 2024-12-29 13:43:50

Glowcoder 是正确的 - 它会永远运行,因为你的线程没有做任何有用的事情。 thrdA 正在等待信号量,thrdB 永远循环而不执行任何操作 - 它应该在某个时刻对信号量执行某些操作,以便 thrdA 可以跳过等待。

Glowcoder is correct - this runs forever because your threads aren't doing anything useful. thrdA is waiting for the semaphore, thrdB is looping forever doing nothing - it should be doing something to the semaphore at some point so that thrdA can get past the wait.

无可置疑 2024-12-29 13:43:50

我一直在网上到处寻找信号量和多线程解决方案,但找不到任何可以阻止线程生成和内存占用的东西。也就是说,如果有 10 亿个数据,而您只需要处理 10 个线程,每个线程一次使用 10000 个数据,我就没有得到更好的解决方案。所以我写了下面的代码来获得正确的答案。

使用这个 semaphore.availablePermits 我能够阻止主线程创建新线程和内存占用。如果您有比这更好的解决方案,请告诉我。我已经测试了 5 亿数据,它显着提高了性能。

public void startTestSemaphore() {
    ExecutorService executor = Executors.newFixedThreadPool(5);
    Semaphore semaphore = new Semaphore(5);
    int count = 1;
    try {
        while (true) {
            if (count == 1000000) {
                break;
            }

            List<String> list = new ArrayList<String>();
            while (count % 100 != 0) {
                list.add(count + "SHSH");
                count++;
            }

            System.out.println(list.size());
            if (!list.isEmpty()) {
                System.out.println("Creatinng new THREAD ");
                Thread t1 = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            semaphore.acquire();
                            System.out.println("EXECUTING THREAD " + Thread.currentThread().getName());
                            TestClassSem sem1 = new TestClassSem();
                            sem1.callThread();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        } finally {
                            semaphore.release();
                        }
                    }
                });
                executor.execute(t1);
                count++;
            }

            while(semaphore.availablePermits()==0) {
                Thread.sleep(2000);
                System.out.println(Thread.currentThread().getName()+" is sleeping bcz other threads are executing");
            }
        }
        executor.shutdown();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            executor.awaitTermination(1, TimeUnit.HOURS);
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }
    }
}

i have been looking for semaphore and multithreading solution everywhere on net but was not able to find anything which stops Thread Generation and Memory occupancy. i.e. if there is a billion data and you just need to process 10 threads each using 10000 data at a single time i was not getting better solutions. so i wrote below code to get correct answers.

using this semaphore.availablePermits i was able to hault main thread from creating new threads and memory occupy. if you got any better solution than this kindly let me know. i have testing if for 500 Million data and it significantly inproved the performance.

public void startTestSemaphore() {
    ExecutorService executor = Executors.newFixedThreadPool(5);
    Semaphore semaphore = new Semaphore(5);
    int count = 1;
    try {
        while (true) {
            if (count == 1000000) {
                break;
            }

            List<String> list = new ArrayList<String>();
            while (count % 100 != 0) {
                list.add(count + "SHSH");
                count++;
            }

            System.out.println(list.size());
            if (!list.isEmpty()) {
                System.out.println("Creatinng new THREAD ");
                Thread t1 = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            semaphore.acquire();
                            System.out.println("EXECUTING THREAD " + Thread.currentThread().getName());
                            TestClassSem sem1 = new TestClassSem();
                            sem1.callThread();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        } finally {
                            semaphore.release();
                        }
                    }
                });
                executor.execute(t1);
                count++;
            }

            while(semaphore.availablePermits()==0) {
                Thread.sleep(2000);
                System.out.println(Thread.currentThread().getName()+" is sleeping bcz other threads are executing");
            }
        }
        executor.shutdown();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            executor.awaitTermination(1, TimeUnit.HOURS);
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文