上周五去面试,面试官出了一道多线程对Stack操作的题目。我华丽丽的说没用过,被深深地鄙视了。因为2年得框架开发经验,对多线程没有任何关注,这么简单的题目都答不上,真是要痛定思痛。
package TestThread.com;
public class Node {
private String data;
private Node next;
public Node(String obj){
this.data=obj;
next=null;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
}
这是节点类,本来想把data设置为Object类型,但是在后台打Push or Pop的内容是,object对象转换不成String对象,结果不直观,所以改成了String的实现,我很诧异,因为如下代码是可以的:
package test;
public class test1 {
public static void main(String[] args){
Object o=new String("111");
System.out.println(o.toString());
System.out.println((String)o);
}
}
输出结果都是111.
接下来是StackList类,有2个主要的方法insertAtFront就是往栈顶插元素,removeFromFirst是往栈顶Pop元素。isEmpty是判断是否为空。这3个方法都用了synchronize关键字,也就是同一时间只能有一个线程使用这些方法。
package TestThread.com;
public class StackList {
private Node head;
public StackList(){
head=null;
}
public synchronized boolean isEmpty(){
return head==null;
}
public synchronized void insertAtFront(Node obj){
Node newHead=new Node(obj.getData());
newHead.setNext(head);
head=newHead;
System.out.println("Push:"+(String)head.getData());
notify();
}
public synchronized Object removeFromFirst() throws InterruptedException{
if(this.isEmpty()){
this.wait();
}
Node firstHead=head;
head=head.getNext();
System.out.println("Pop:"+(String)firstHead.getData());
return firstHead.getData();
}
}
然后是2个线程的实现,Push线程是往栈里面塞1000个元素,Pop是不停的取,如果为空那么wait。
package TestThread.com;
public class ThreadPush implements Runnable{
private StackList sl;
public ThreadPush(StackList sl){
this.sl=sl;
}
public void run() {
for(int i=0;i<1000;i++){
Node node=new Node(new String("Node"+i));
sl.insertAtFront(node);
}
}
}
package TestThread.com;
public class ThreadPop implements Runnable{
private StackList sl;
public ThreadPop(StackList sl){
this.sl=sl;
}
public void run() {
try {
while(true){
sl.removeFromFirst();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
最后是测试类。
package TestThread.com;
public class ThreadTest {
public static void main(String[] args){
StackList ls=new StackList();
ThreadPop tpp=new ThreadPop(ls);
ThreadPush tph=new ThreadPush(ls);
new Thread(tph).start();
new Thread(tpp).start();
}
}
结果如下:
Push:Node0
Pop:Node0
Push:Node1
Pop:Node1
Push:Node2
Pop:Node2
Push:Node3
Pop:Node3
Push:Node4
Pop:Node4
Push:Node5
Pop:Node5
Push:Node6
Push:Node7
Push:Node8
后面太多了,就不贴了。这是一个很简单的实现。反正这种东西呢,平时接触了就知道,不接触就不知道,我真是吃了这方面的亏啊。