在阅读了关于信号量之后,我尝试了这个测试代码,其中我创建了两个线程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();
}
}
答案 0 :(得分:2)
您的代码中存在许多问题。
Semaphore
。while(true)
给CPU带来了沉重的负担。请考虑使用Thread.sleep
或获取信号量/锁定。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();
}
}
}