我目前正在开展一个项目,在这个项目中我基本上有10个线程正在睡觉#34;这10个线程中的一个是随机唤醒"唤醒"并开始做一些工作。我只是想看看我是否朝着正确的方向前进。因此,我应该只创建线程的每个实例。
Thread thread0 = new Thread(new doWork());
...
Thread thread9 = new Thread(new doWork());
只是没有启动它们然后当他们要醒来时#34;只需在特定线程上调用start()
方法..
或者我应该启动每个帖子,但是在我调用wait()
方法之前让它们notify()
?
或者我应该启动该主题并使用sleep()
然后调用interrupt()
方法吗?
哪种方法似乎更好,为什么?
非常感谢任何见解。
编辑这是否可以接受?
import java.util.Random;
public class Client {
private static Thread [] clients = new Thread[10];
public static void main(String[] args){
createClients();
randomWake();
}// end main()
static void createClients(){
Thread client0 = new Thread(new ClientThread(0));
clients[0] = client0;
Thread client1 = new Thread(new ClientThread(1));
clients[1] = client1;
Thread client2 = new Thread(new ClientThread(2));
clients[2] = client2;
Thread client3 = new Thread(new ClientThread(3));
clients[3] = client3;
Thread client4 = new Thread(new ClientThread(4));
clients[4] = client4;
Thread client5 = new Thread(new ClientThread(5));
clients[5] = client5;
Thread client6 = new Thread(new ClientThread(6));
clients[6] = client6;
Thread client7 = new Thread(new ClientThread(7));
clients[7] = client7;
Thread client8 = new Thread(new ClientThread(8));
clients[8] = client8;
Thread client9 = new Thread(new ClientThread(9));
clients[9] = client9;
for(int i = 0; i < clients.length; i++)
clients[i].start();
}// end createClients()
static void randomWake(){
Random rand = new Random();
int randomNumber = rand.nextInt(10);
clients[randomNumber].interrupt();
}// end randomWake()
static class ClientThread implements Runnable{
private int clientNumber;
public ClientThread(int clientNumber){
this.clientNumber = clientNumber;
}// end ClientThread(int clientNumber)
public void run(){
while(!Thread.interrupted()){}
System.out.println("Client " + clientNumber + " is awake!");
}// end run()
}// end class ClientThread
} //结束类客户端
答案 0 :(得分:0)
如果有最长的睡眠时间
您可能需要实现以下Thread
类:
public class DoWork extends Thread {
public void run () {
while(true) {
Thread.Sleep((int) Math.floor(Math.random()*10000));
//do some work
}
}
}
其中10000
是线程应该睡眠的最长时间(以毫秒为单位)。
如果没有最大睡眠时间
您可能需要实现以下Thread
类:
public class DoWork extends Thread {
public void run () {
while(true) {
Thread.Sleep(1);
if(Math.random() < 0.005d) {
//do some work
}
}
}
}
其中0.005
是运行方法一定毫秒的概率。
notify
和wait
用于实现信号量:这是防止两个线程同时操作同一个对象的对象(因为某些对象可能会结束)在一个非法的国家)。
答案 1 :(得分:0)
如何使用信号量?
class DoWork extends Runnable {
private final Semaphore semaphore;
DoWork(Semaphore semaphore) {
this.semaphore = semaphore;
}
@Override
public void run() {
while (true) {
semaphore.acquire();
//do some work
}
}
}
主程序可以创建一个信号量数组,以及运行DoWork实例的相同数量的线程,这样每个DoWork实例都有自己的信号量。每次主程序调用sema [i] .release()时,相应DoWork实例的run()方法将执行一些工作&#34;然后回去等待。
答案 2 :(得分:0)
你的答案没有多大意义,所以不确定你真正想要实现的目标。但是对于你描述的内容,你应该把所有线程放在同一个锁上,然后通知锁(它只会随机唤醒一个)
但是,由于这没有多大意义,我想你想要实现不同的东西。
检查有关睡眠与等待的问题:Difference between wait() and sleep()
答案 3 :(得分:0)
检查一下。如果我不使用ThreadPooling(这是其他人所说的非常正确),这就是我将如何解决它,以便我可以看到wait()
,notify()
和Thread.sleep()
是如何工作的。检查谷歌,您会看到(例如Thread.sleep and object.wait)主要wait()
和notify()
用于线程之间的通信,并使用Thread.sleep
,以便您可以暂停您的程序。< / p>
- 这个答案的部分内容基于:http://tutorials.jenkov.com/java-concurrency/thread-signaling.html#missedsignals。您可以检查代码以查看您需要采取的步骤(注释掉代码的某些部分)以使程序挂起,以便您了解如何处理丢失的信号。程序挂起所需的迭代不是固定的。
- 该程序将永远运行。为了解决这个问题,您需要对其进行一些处理。
主要强>
public class Main
{
public static void main(String[] args)
{
Manager mgr = new Manager("manager");
mgr.start();
}
}
经理
public class Manager extends Thread
{
private final Object lock = new Object();
private boolean wasSignalled = false;
private DoWork[] workThreads = new DoWork[5];
public Manager(String name){
super(name);
workThreads[0] = new DoWork(this,"work 0");
workThreads[1] = new DoWork(this,"work 1");
workThreads[2] = new DoWork(this,"work 2");
workThreads[3] = new DoWork(this,"work 3");
workThreads[4] = new DoWork(this,"work 4");
}
public void wakeUP()
{
synchronized (this.lock) {
wasSignalled = true;
this.lock.notify();
}
}
public void pauseAndWait()
{
synchronized (this.lock) {
if(!wasSignalled)
{
try {
this.lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//clear signal and continue running.
wasSignalled = false;
}
}
public void run ()
{
int i=0;
while(true)
{
i++;
System.out.println(" manager ...: "+i+" ");
int choose = 0 + (int)(Math.random() * ((4 - 0) + 1));
//choose=0; for debugginng
if(!workThreads[choose].isAlive()){
workThreads[choose].start();
}
else{
workThreads[choose].wakeUP();
}
//wait to be notified by DoWork thread when its job
//is done
pauseAndWait();
}
}
}
DoWork
public class DoWork extends Thread
{
private final Object lock = new Object();
private boolean wasSignalled = false;
private Manager managerThread;
public DoWork(Manager managerThread,String name){
super(name);
this.managerThread=managerThread;
}
public void wakeUP()
{
synchronized (this.lock) {
//check what happens without wasSignalled flag
//step #1: comment out wasSignalled = true;
wasSignalled = true;
this.lock.notify();
}
}
public void pauseAndWait()
{
synchronized (this.lock) {
//check what happens without wasSignalled flag
//step #2: comment out the if block
if(!wasSignalled)
{
try {
this.lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//check what happens without wasSignalled flag
//step #3: comment out wasSignalled = false;
//clear signal and continue running.
wasSignalled = false;
}
}
public void run ()
{
int i=0;
while(true)
{
i++;
try {
System.out.print(this.getName()+" going to sleep ...: "+i+" ");
//check what happens without wasSignalled flag
//step #4: put sleep time to Thread.sleep(0);
//simulate worker thread job
Thread.sleep(1000);
System.out.println(" woke up ... ");
} catch (InterruptedException e) {
System.out.println(" worker thread: job simulation error:"+e);
}
//if worker thread job simulation is done (sleep for 4 times)
//then suspend thread and wait to be awaken again
if(i>4)
{
System.out.println(this.getName()+" notifying main ...: "+i+" \n");
i=0;
managerThread.wakeUP();
// thread does not get destroyed, it stays in memory and when the manager
// thread calls it again it will wake up do its job again
pauseAndWait();
}
}
}
}