信号量和线程问题

时间:2011-12-22 06:02:26

标签: java multithreading semaphore

在阅读了关于信号量之后,我尝试了这个测试代码,其中我创建了两个线程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();

  }
}

3 个答案:

答案 0 :(得分:2)

您的代码中存在许多问题。

  1. 正如评论和答案中所述,如果您想等待/通知您不必使用Semaphore
  2. while(true)给CPU带来了沉重的负担。请考虑使用Thread.sleep或获取信号量/锁定。
  3. 您需要详细说明您想要实现的目标。如果你想让threadB等待threadA你不需要任何信号量/锁。在thread1.join()进行任何其他调用之前,只需致电thread2.run

答案 1 :(得分:0)

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

答案 2 :(得分:0)

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

使用此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();
        }
    }
}