一、线程同步问题
public class TestSynchThread implements Runnable{
static int k = 100;public synchronized static void m1(){
k=1000;try{Thread.sleep(1100);System.out.println("子线程执行结果k:"+k);}catch(InterruptedException e){return;}
}
/* m2方法加锁之后,程序最终的输出结果是:子线程执行结果K:1000,MAIN线程执行结果:1000,为什么main线程也是1000呢,是因为t1线程执行完成之后,紧接着执行m2方法,但是M2方法却睡了,此时,直接跳入执行下一个语句,输出了结果。但是如果,t1线程睡眠的时间大于m2方法的休眠时间,那么结果又会出现不同 */
public synchronized static void m2(){try{Thread.sleep(2000);}catch(InterruptedException e){return;}k=2000;}
public static void main(String[] args){TestSynchThread tst = new TestSynchThread();Thread t1 = new Thread(tst);t1.start();tst.m2();System.out.println("main 线程执行结果:"+k);}
public void run(){m1();}
}
//输出结果为:子线程执行结果k:1000;main线程执行结果:2000;
分析原因:首先执行t1线程,K的值变为1000;此时main线程同时也在执行,但是由于m2方法中,线程sleep为2秒,而t1线程只sleep 1秒,所以t1线程先输出了“子线程执行结果”,之后M2方法在完成2秒的睡眠后,开始执行,并将k的值设置为2000,最后主线程输出结果为2000。这里如果M2方法不加锁,就需要根据睡眠时间的长短来判断K的值了
但是如果M2方法此时加锁之后,输出结果就会出现不同。
二、生产者消费者问题
public class TestSynchThread2{
public static void main(String[] args){
WotouSynStack wss = new WotouSynStack();Thread t1 = new Thread(new Producer(wss));Thread t2 = new Thread(new Consumer(wss));t1.start();t2.start();
}
}
class Wotou{
int id=0;int index=0;Wotou(int id){
this.id=id;
}
public String toString(){return "Wotou--Id:" + id;}
}class WotouSynStack{
Wotou[] arrWt = new Wotou[6];int index=0;public synchronized void push(Wotou wt){ //添加时,可以不需要返回值
if(index == arrWt.length){ //原来的判断是小于这里判断的条件需要修改为==,而且要注意判断语句控制的范围
try{this.wait() ;//要使用wait方法必须主要配合notify方法使用}catch(InterruptedException e){e.printStackTrace();}
}
this.notify();arrWt[index]=wt;index++;
}
public synchronized Wotou pop(){//这里不需要有参数因为拿出来得时候默认从数组中拿出
//wts[index]=wt;//index--;if(index==0){//注意这里的判断用的是if才行 ,用while有问题
try{/ /这里使用wait方法而不能使用sleep方法
this.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
}this.notify();index--;return arrWt[index];}
}
class Producer implements Runnable{
WotouSynStack wss = null;Producer(WotouSynStack wss){
this.wss=wss;
}public void run(){
for(int i=0;i<20;i++){//这里是使用构造方法创建对象,而却糊里糊涂使用了数组,提示不兼容的对象,就要看看返回值问题
Wotou wt =new Wotou(i);wss.push(wt);System.out.println("生产了:"+wt);
try{Thread.sleep(100); //这里很重要如果不进行睡眠的话,会一直生产}catch (InterruptedException e){e.printStackTrace();}
}
}
}
class Consumer implements Runnable{
WotouSynStack wss = null;Consumer(WotouSynStack wss){
this.wss = wss;
}
public void run(){ //这里少了一个for循环取出所以,每次输出结果都只有一个consumer
for(int i=0;i<20;i++){Wotou wt = wss.pop();System.out.println("消费了:"+wt);try{Thread.sleep(1000); //这里很重要 ,这样才能清晰看出}catch (InterruptedException e){e.printStackTrace();}}
}
}
//错误提示问题说明:
//错误提示问题说明:
出现这个错误的原因主要是: 程序里面少写了一个大括号