首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > J2SE开发 >

java多线程,该如何解决

2012-01-21 
java多线程我想实现一个两个线程对同一个变量,一个线程加,一个线程减的程序。可是打印的结果是1,2,3,4,5,6,

java多线程
我想实现一个两个线程对同一个变量,一个线程加,一个线程减的程序。可是打印的结果是1,2,3,4,5,6,7...而不是1,0,1,0..
想知道为什么
程序如下:

Java code
public class Core {    public static void main(String[] args) throws Exception{        Operation op = new Operation();        WorkerBear b1 = new WorkerBear(op);        EatBear b2 = new EatBear(op);        Thread t1 = new Thread(b1);        Thread t2 = new Thread(b2);        t2.start();        t1.start();    }}

Java code
public class WorkerBear implements Runnable{    private Operation op;        public WorkerBear(Operation op){        this.op = op;    }        @Override    public void run() {        // TODO Auto-generated method stub        while(true){        op.increment();        }    }}

Java code
public class EatBear implements Runnable{    private Operation op;        public EatBear(Operation op){        this.op = op;    }    @Override    public void run() {        // TODO Auto-generated method stub        while(true){ //如果这里加入一个Thread.sleep()就好使,为什么呢        op.decrement();        }    }}

Java code
public class Operation {    int box = 0 ;        public synchronized void increment() {        box++;        try {            Thread.sleep(1000);        System.out.println(box);        } catch (InterruptedException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }    public synchronized void decrement() {        box--;        try {            Thread.sleep(1000);        System.out.println(box);        } catch (InterruptedException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}


[解决办法]
汗,因为你把sleep(1000)放到同步方法里面了...
一个线程sleep的时候,没有释放锁,所以另一个线程无法执行
sleep完释放锁的时候,又没有做线程礼让,或唤醒其他线程的动作,系统把时间片仍然分给该线程,
所以就一直加加加
所以sleep(1000)要放在while循环中才行
[解决办法]
探讨
那为什么我把sleep放在外面的时候B线程就能获得到锁呢,我也是没有唤醒B线程呀

[解决办法]
探讨
是呀,那即使是thread1的increment()方法里面有一个sleep(),当increment()退出的时候,thread2的decrement()不同样是有可能获得cpu吗?为什么事实上只有thread1总是获得cpu呢?这点我不太懂

[解决办法]
这里有个参考例子,希望对你有帮助:
Java code
/** *  */package cn.luochengor.csdn;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.TimeUnit;/** * 实现两个线程对同一个变量,一个线程加,一个线程减的程序 打印的结果是:1,0,1,0.. *  * @Author luochengor * @Date Oct 25, 2011 * @Email luochengor@foxmail.com */public class OneZero {    private int number = 0;    private boolean isOne = false;    public synchronized int toOne() {        number++;        isOne = true;        notifyAll();        return number;    }    public synchronized int toZero() {        number--;        isOne = false;        notifyAll();        return number;    }    public synchronized void waitToOne() throws InterruptedException {        while (!isOne) {            wait();        }    }    public synchronized void waitToZero() throws InterruptedException {        while (isOne) {            wait();        }    }    /**     * @param args     * @throws InterruptedException     */    public static void main(String[] args) throws InterruptedException {        OneZero oz = new OneZero();        ExecutorService exec = Executors.newCachedThreadPool();        exec.execute(new ToOne(oz));        TimeUnit.MILLISECONDS.sleep(50);        exec.execute(new ToZero(oz));        TimeUnit.SECONDS.sleep(5);        exec.shutdownNow();    }}class ToOne implements Runnable {    private OneZero oz;    public ToOne(OneZero oz) {        this.oz = oz;    }    public void run() {        try {            while (!Thread.interrupted()) {                TimeUnit.MILLISECONDS.sleep(600);                System.out.println(oz.toOne());                oz.waitToZero();            }        } catch (InterruptedException e) {            System.out.println("InterruptedException class ToOne");        }    }}class ToZero implements Runnable {    private OneZero oz;    public ToZero(OneZero oz) {        this.oz = oz;    }    public void run() {        try {            while (!Thread.interrupted()) {                TimeUnit.MILLISECONDS.sleep(600);                System.out.println(oz.toZero());                oz.waitToOne();            }        } catch (InterruptedException e) {            System.out.println("InterruptedException class ToZero");        }    }} 

热点排行