在JAVA中睡觉的线程

时间:2014-04-17 15:05:45

标签: java multithreading sleep wait

我目前正在开展一个项目,在这个项目中我基本上有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

} //结束类客户端

4 个答案:

答案 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是运行方法一定毫秒的概率。


notifywait用于实现信号量:这是防止两个线程同时操作同一个对象的对象(因为某些对象可能会结束)在一个非法的国家)。

答案 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();
            }
        }
    }
}