今天听说一个公司的面试替,写出来14K,写不出来8k,立马不看答案手搓了一波 ,感觉就是生产者消费者的问题
上代码:
package com.czy.one;
public class Showabc {
private int flag=0;
private int count;
public synchronized void showA(){
//0输出
while(flag!=0 && count<10){
try {
this.wait();
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
System.out.print(Thread.currentThread().getName()+"-");
flag++;
this.notifyAll();
}
public synchronized void showB(){
while(flag!=1 && count<10){
try {
this.wait();
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
System.out.print(Thread.currentThread().getName()+"-");
flag++;
this.notifyAll();
}
public synchronized void showC(){
while(flag!=2 && count<10){
try {
this.wait();
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
System.out.print(Thread.currentThread().getName()+"-");
flag=0;
count++;
this.notifyAll();
}
public static void main(String[] args) {
Showabc abc=new Showabc();
A a=new A(abc);
B b=new B(abc);
C c=new C(abc);
new Thread(a,"A").start();
new Thread(b,"B").start();
new Thread(c,"C").start();
}
}
class A implements Runnable{
private Showabc abc=new Showabc();
public A(Showabc abc) {
// TODO 自动生成的构造函数存根
this.abc=abc;
}
@Override
public void run() {
// TODO 自动生成的方法存根
for(int i=0;i<10;i++)
abc.showA();
}
}
class B implements Runnable{
private Showabc abc=new Showabc();
public B(Showabc abc) {
// TODO 自动生成的构造函数存根
this.abc=abc;
}
@Override
public void run() {
// TODO 自动生成的方法存根
for(int i=0;i<10;i++)
abc.showB();
}
}
class C implements Runnable{
private Showabc abc=new Showabc();
public C(Showabc abc) {
// TODO 自动生成的构造函数存根
this.abc=abc;
}
@Override
public void run() {
// TODO 自动生成的方法存根
for(int i=0;i<10;i++)
abc.showC();
}
}
个人感觉这类多线程切换问题有两个地方需要注意:
A)要以唤醒来结尾,this.notifyAll();
如果不以唤醒结尾,那么很有可能最后一个形成运行到最后,并没有结束,而是一直等待;
B)要加上循环判断,可以把wait放在循环判断的最后
因为我们唤醒线程时,是以wait后继续后行,那么如果wait在判断中,那么在次进入时,我们不能保证本次运行是符合条件的,
所以加上循环判断,不符合再次等待;
当然,最重要的一点就是请14K联系我一下............