黑马程序员技术交流社区

标题: 多线程对共享数据的访问 [打印本页]

作者: 新手ing    时间: 2015-7-19 11:55
标题: 多线程对共享数据的访问
本帖最后由 新手ing 于 2015-7-19 15:35 编辑

1、写一个程序,两个线程Input和Output。Input交替写数据,output负责读数据。

public class Demo11 {
    /**
     * 多线程对共享数据的操作
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
    Resource r = new Resource();
    Thread in = new Thread(new Input(r));
    Thread out = new Thread(new Output(r));
    in.start();
    out.start();
    }
}
class Input implements Runnable{
    private Resource r;
    Input(Resource r){
        this.r = r ;
    }
    boolean flag = true;
    public void run(){
        while(true){
            if(flag){
                r.name = "zhangsan";
                r.sex = "男";
                flag = false;
            }else{
                r.name = "lili";
                r.sex = "女";
                flag = true;
            }
        }
    }
}
class Output implements Runnable{
    private Resource r;
    Output(Resource r){
        this.r = r;
    }
    public void run(){
         while(true){
             System.out.println(r.name+"......"+r.sex);
         }
    }
}
class Resource{
    String name ;
    String sex ;
}
从输出结果可以看到:lili输出了男,zhangsan输出了女。为什么会出现这种状况?对共享数据访问时,顺序出现了错误,还没等Input线程处理完,Output开始输出。看一下改进版。
public class Demo11 {

    /**
     * 多线程对共享数据的操作
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Resource r = new Resource();
        Thread in = new Thread(new Input(r));
        Thread out = new Thread(new Output(r));
        in.start();
        out.start();
    }

}

class Input implements Runnable {
    private Resource r;
    Input(Resource r) {
        this.r = r;
    }
    boolean flag = true;
    public void run() {
        while (true) {
            synchronized (r) {
                if (flag) {
                    r.name = "zhangsan";
                    r.sex = "男";
                    flag = false;
                } else {
                    r.name = "lili";
                    r.sex = "女";
                    flag = true;
                }
            }
        }
    }
}

class Output implements Runnable {
    private Resource r;
    Output(Resource r) {
        this.r = r;
    }
    public void run() {
        while (true) {
            synchronized (r) {
                System.out.println(r.name + "......" + r.sex);
            }
        }
    }
}
class Resource{
    String name ;
    String sex ;
}
现在更改一下需求:要求zhangsan和lili交替输出。
public class Demo11 {

    /**
     * 多线程对共享数据的操作
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Resource r = new Resource();
        Thread in = new Thread(new Input(r));
        Thread out = new Thread(new Output(r));
        in.start();
        out.start();
    }

}

class Input implements Runnable {
    private Resource r;
    Input(Resource r) {
        this.r = r;
    }
    boolean flag = true;
    public void run() {
        int x = 0;
        while (true) {
            synchronized (r) {
                if(r.flag){
                    try {
                        r.wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                if (x==0) {
                    r.name = "zhangsan";
                    r.sex = "男";
                } else {
                    r.name = "lili";
                    r.sex = "女";
                }
                x=(x+1)%2;
                r.flag = true;
                r.notify();
            }
        }
    }
}

class Output implements Runnable {
    private Resource r;
    Output(Resource r) {
        this.r = r;
    }
    public void run() {
        while (true) {
            synchronized (r) {
                if(!r.flag){
                    try {
                        r.wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                System.out.println(r.name + "......" + r.sex);
                r.flag = false;
                r.notify();
            }
        }
    }
}
class Resource{
    String name ;
    String sex ;
    boolean flag = false;
}
代码优化一下
public class Demo11 {

    /**
     * 多线程对共享数据的操作
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Resource r = new Resource();
        Thread in = new Thread(new Input(r));
        Thread out = new Thread(new Output(r));
        in.start();
        out.start();
    }

}

class Input implements Runnable {
    private Resource r;
    Input(Resource r) {
        this.r = r;
    }
    boolean flag = true;
    public void run() {
        int x = 0;
        while (true) {
            if(x==0){
                r.set("zhangsan", "男");
            }else{
                r.set("lili", "女");
            }
            x = (x+1)%2;
        }
    }
}
class Resource{
    private String name ;
    private String sex ;
    boolean flag = false;
    public synchronized void set(String name ,String sex){
        if(flag){
            try {
                this.wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        this.name = name ;
        this.sex = sex;
        flag = true;
        this.notify();
    }
    public synchronized void info(){
        if(!flag){
            try {
                this.wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        System.out.println(name + "......" + sex);
        flag = false;
        this.notify();
    }
    }
class Output implements Runnable {
    private Resource r;
    Output(Resource r) {
        this.r = r;
    }
    public void run() {
        while (true) {
            r.info();
        }
    }
}





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2