java添加睡眠时间_java – 让runnable进入睡眠状态

我有一个Java问题.我想编写一个程序,其中有Class Main,它有一些类的ThreadList(Class Task),它只写一个字母和数字. Object Main只是从ArrayList中唤醒一个Thread,让它在同一个对象(Main)睡眠另一个时执行某些操作.

它工作正常:

0A,0B,0C,1B,1C,1A,2B,2A,2C,3B,3C,3A,4B,4C,4A,5B,5A,5C,

但只有我评论:

e.printStackTrace()e是异常

然后

我得到了很多

java.lang.IllegalMonitorStateException

at java.lang.Object.notify(Native Method)

在Main.run(Main.java:22)

所以通知工作错误,我应该如何正确唤醒它,请告诉我,显示,正确.请

import java.util.ArrayList;

import java.util.ArrayList;

public class Main extends Thread {

ArrayList threads;

public Main() {

super();

threads = new ArrayList();

}

public void run() {

for (int i = 0; i < 3; i++) {

threads.add(new Thread(new Task(i + 65)));

}

long cT = System.currentTimeMillis();

for (int i = 0; i < threads.size(); i++) {

threads.get(i).start();

}

while (System.currentTimeMillis() - cT < 10000) {

for (int i = 0; i < threads.size(); i++) {

try {

threads.get(i).notify();

// HOW TO WAKE THREAD FROM threads ArrayList

Thread.sleep(1000);

// how to put to bed the same thread ?

threads.get(i).wait();

} catch (Exception e) {

e.printStackTrace();

}

}

}

}

public static void main(String[] args) {

new Main().start();

//new Thread(new Task(65)).start();

}

}

H

public class Task implements Runnable {

int nr;

char character;

public Task(int literaASCII) {

this.nr = 0;

character = (char) (literaASCII);

}

@Override

public void run() {

while (true) {

try {

System.out.print(nr + "" + character + ", ");

nr++;

int r = (int) ((Math.random() * 500) + 500); // <500ms,1000ms)

Thread.sleep(r);

} catch (Exception e) {

e.printStackTrace();

}

}

}

public static void main(String[] args) {

// TODO Auto-generated method stub

}

}

解决方法:

睡觉和等待是非常不同的. sleep只是暂停当前线程达到指定的时间,并且没有与其他线程直接交互.

等待更复杂:等待的想法是暂停给定监视器上的线程(或锁定,如果你愿意)并让其他线程工作,直到它通知该监视器并释放它.因此,等待和通知涉及两个或多个线程之间的交互.

由于这种交互,为了使wait和notify正常工作,调用这些方法的线程必须拥有监视器(锁),这意味着必须从内部调用object.wait()或object.notify() synchronized(object){…}块.如果在没有synchronized-block的情况下调用object.wait(),则总会遇到IllegalMonitorStateException.

在你的代码中,

for (int i = 0; i < threads.size(); i++) {

threads.get(i).start();

}

这将启动所有线程,然后将同时运行所有线程,而不是一次一个地运行它们.

要确保一次只运行一个线程,您需要将一个公共监视器对象传递给所有线程并让它们在该监视器上等待.例如:

public class Main extends Thread {

//...

public void run(){

//Initialize all threads with common monitor object

Object monitor = new Object();

for (int i = 0; i < 3; i++) {

threads.add(new Thread(new Task(i + 65, monitor)));

}

long cT = System.currentTimeMillis();

for (int i = 0; i < threads.size(); i++) {

//All threads will start, and immediately pause on monitor.wait()

threads.get(i).start();

}

synchronized(monitor){

while (System.currentTimeMillis() - cT < 10000) {

//All threads are currently waiting, so we need to wake one random

//thread up by calling notify on monitor. Other thread will not run yet,

//because this thread still holds the monitor.

monitor.notify();

//Make this thread wait, which will temporarily release the monitor

//and let the notified thread run.

monitor.wait();

}

}

}

}

//...

public class Task implements Runnable{

int nr;

char character;

Object monitor;

public Task(int literaASCII, Object monitor) {

this.nr = 0;

this.monitor = monitor;

character = (char) (literaASCII);

}

@Override

public void run() {

synchronized(monitor){

while (true) {

//Pause this thread and let some other random thread

//do the work. When other thread finishes and calls notify()

//this thread will continue (if this thread is picked).

monitor.wait();

try {

System.out.print(nr + "" + character + ", ");

nr++;

int r = (int) ((Math.random() * 500) + 500); // <500ms,1000ms)

Thread.sleep(r);

} catch (Exception e) {

e.printStackTrace();

}

//This thread has finished work for now.

//Let one other random thread know.

monitor.notify();

//Other thread will not be able to do work until this thread

//releases the monitor by calling monitor.wait() or

//completely exists the synchronized(monitor){ ... } block.

}

}

}

}

它可能与您的初衷略有不同,因为线程会随机唤醒,因此无法保证输出将以任何特定顺序排列.

另请注意,除非您有充分的理由使用notify(),否则您应该首选notifyAll()来notify().因为notify()只唤醒一个线程,如果该线程“忘记”最后调用notify,则所有其他线程可能永远等待.

标签:java,multithreading,notify

来源: https://codeday.me/bug/20190713/1450885.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值