论坛首页 招聘求职论坛

以前为公司出的一道面试题,有点偏,有兴趣的可以试试

浏览 34248 次
精华帖 (0) :: 良好帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-06-07  
抛出异常的爱 写道
Thread-0 is running....
java.lang.IllegalMonitorStateException: current thread not owner
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Unknown Source)
at com.maodajun.lib.Stack.pop(Stack.java:51)
at com.maodajun.lib.ThreadWait$1.run(ThreadWait.java:35)
Thread-0 end....
Thread-1 is running....
java.lang.IllegalMonitorStateException: current thread not owner
at java.lang.Object.notify(Native Method)
at com.maodajun.lib.Stack.push(Stack.java:42)
at com.maodajun.lib.ThreadWait$2.run(ThreadWait.java:46)

报错。。。不知道为什么。。。


因为监视器使用不当,他synchronized的是list,但却调用的是this.wait()和this.notify(),将他代码里的wait()/notify()修改成list.wait()/list.notify()就可以了。
0 请登录后投票
   发表时间:2007-06-08  
Godlikeme 写道
不用这么较真,大体意思明白就行了。
线程上下文切换,什么意思?

java language spec中 强调了 notify()/if的风险,
建议使用notifyAll()/while,性能差点总比出问题好。


对性能的要求,看你是搭狗棚还是盖摩天大楼了,前者随你怎么整都可以,如果你要盖大楼,比方说20w+在线2000+并发的jabber服务器,那压榨一点点性能都是值的。

堵塞通常代表着更多线程(毕竟线程要等在那里而不是做其它工作),因此当操作系统进行线程调度的次数也会增加(线程多了),cpu忙于上下文切换的消耗也会随之增大,这也就是拥有1000个线程并不代表能处理1000并发的原因所在。
0 请登录后投票
   发表时间:2007-06-08  
这就扯出另一个话题了,跟这个考题没啥关系了。
如何减少线程数(减少上下文切换,还有调度的问题)是系统设计的问题,并不是synchronized加的地方对不对这么简单了。当然也不是这道题要考的东西。
0 请登录后投票
   发表时间:2007-06-14  
Hope this can help you to understand wait/notifyAll better
package thread;

import java.util.LinkedList;

import org.apache.log4j.Logger;

public class ThreadWait {

	public static void main(String[] args) {
		final Logger logger = Logger.getLogger(ThreadWait.class);
		final Stack stack = new Stack();
		Thread t1 = new Thread("PopThread") {
			public void run() {
				
				logger.info(Thread.currentThread().getName()
						+ " is running....");
				Object o = null;
				try {
					o = stack.pop();
				} catch (Exception e) {
					e.printStackTrace();
				}
				logger.info("o=" + o);
				logger.info(Thread.currentThread().getName()
						+ " end....");
			}
		};
		Thread t2 = new Thread("PushThread") {
			public void run() {
				try {
					Thread.sleep(1000);
				} catch (Exception e) {
					e.printStackTrace();
				}
				logger.info(Thread.currentThread().getName()
						+ " is running....");
				stack.push(new Object());
				logger.info(Thread.currentThread().getName()
						+ " end....");
			}
		};
		t1.start();
		t2.start();
	}
}

class Stack {
	LinkedList list = new LinkedList();

	Logger logger = Logger.getLogger(Stack.class);

	public synchronized void push(Object x) {
		showThisLockOwner();
		synchronized (list) {
			showListLockOwner();
			list.addLast(x);
			notifyAll();
			logger.info("push done");
		}
	}

	public synchronized Object pop() {
		showThisLockOwner();
		synchronized (list) {
			showListLockOwner();
			while (list.size() <= 0) {
				try {
					logger.info("start list.wait(1000)");
					list.wait(1000);
					logger.info("finish list.wait(1000)");
					showThisLockOwner();
					showListLockOwner();
					logger.info("start wait(1000)");
					wait(1000);
					logger.info("finish wait(1000)");
					showListLockOwner();
					showThisLockOwner();
					logger.info("finish wait");
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			return list.removeLast();
		}
	}
	
	public void showThisLockOwner() {
		if (Thread.holdsLock(this)) {
			logger.info("Acquired the monitor lock on this");
		}
	}

	public void showListLockOwner() {
		if (Thread.holdsLock(list)) {
			logger.info("Acquired the monitor lock on list");
		}
	}

}



引用

2007-06-13 11:38:38,945 [PopThread] - PopThread is running.... - (thread.ThreadWait$1:15)
2007-06-13 11:38:38,951 [PopThread] - Acquired the monitor lock on this - (thread.Stack:89)
2007-06-13 11:38:38,956 [PopThread] - Acquired the monitor lock on list - (thread.Stack:95)
2007-06-13 11:38:38,958 [PopThread] - start list.wait(1000) - (thread.Stack:68)
//Releases the monitor lock on list object, still holds the monitor lock on this object
2007-06-13 11:38:39,947 [PushThread] - PushThread is running.... - (thread.ThreadWait$2:35) //Waiting for the monitor lock on this object
2007-06-13 11:38:39,960 [PopThread] - finish list.wait(1000) - (thread.Stack:70) //Wakes up after 1 second and resumes the monitor lock on list object
2007-06-13 11:38:39,960 [PopThread] - Acquired the monitor lock on this - (thread.Stack:89)
2007-06-13 11:38:39,962 [PopThread] - Acquired the monitor lock on list - (thread.Stack:95)
2007-06-13 11:38:39,964 [PopThread] - start wait(1000) - (thread.Stack:73)
//Releases the monitor lock on this object, still holds the monitor lock on list object
2007-06-13 11:38:39,964 [PushThread] - Acquired the monitor lock on this - (thread.Stack:89)
//Now PushThread owns the monitor lock on this object while PopThread owns the monitor lock on list object and both are waiting for the other to release the lock. This is a deadlock situation.
0 请登录后投票
   发表时间:2007-06-14  
max.h.chen 写道
这就扯出另一个话题了,跟这个考题没啥关系了。
如何减少线程数(减少上下文切换,还有调度的问题)是系统设计的问题,并不是synchronized加的地方对不对这么简单了。当然也不是这道题要考的东西。


线程池,将线程控制在一定数量吧,一般的应用,线程不会有那么多吧,超过100个已经很恐怖了。
0 请登录后投票
论坛首页 招聘求职版

跳转论坛:
Global site tag (gtag.js) - Google Analytics