加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

Java中简单多线程程序的奇怪问题

发布时间:2020-12-15 08:37:42 所属栏目:Java 来源:网络整理
导读:我刚开始玩多线程编程.我希望我的节目交替显示字符’ – ‘和”,但事实并非如此.我的任务是使用synchronized关键字.到目前为止我有: class FunnyStringGenerator{ private char c; public FunnyStringGenerator(){ c = '-'; } public synchronized char nex
我刚开始玩多线程编程.我希望我的节目交替显示字符’ – ‘和”,但事实并非如此.我的任务是使用synchronized关键字.到目前为止我有:

class FunnyStringGenerator{

    private char c;

    public FunnyStringGenerator(){
        c = '-';
    }

    public synchronized char next(){

        if(c == '-'){
            c = '+';
        }
        else{
            c = '-';
        }

        return c;
    }
}

class ThreadToGenerateStr implements Runnable{

    FunnyStringGenerator gen;

    public ThreadToGenerateStr(FunnyStringGenerator fsg){
        gen = fsg;
    }

    @Override
    public void run() {
        for(int i = 0; i < 10; i++){

            System.out.print(gen.next());
        }
    }


}

public class Main{


    public static void main(String[] args) throws IOException {

        FunnyStringGenerator FSG = new FunnyStringGenerator();

        ExecutorService exec = Executors.newCachedThreadPool();

        for(int i = 0; i < 20; i++){
            exec.execute(new ThreadToGenerateStr(FSG));
        }

    }

}

编辑:我也在run方法中测试Thread.sleep而不是循环.

解决方法

您在FunnyStringGenerator.next()中的同步块工作正常.它将交替返回”和’ – ‘.

但是,你在ThreadToGenerateStr.run()中有一个竞争条件:

System.out.print(gen.next());

这相当于:

char c = gen.next(); // Synchronized
System.out.print(c); // Not synchronized

问题发生在:

>线程1调用gen.next(),得到’ – ‘的结果
>线程2调用gen.next(),得到”的结果
>线程2调用System.out.print(),写”
>线程1调用System.out.print(),写’ – ‘

结果是”和’ – ‘以相反的顺序写入.

有各种可能的解决方法,例如:

>在单个同步块中调用gen.next()和System.out.print()(如dogbane的答案)
> make gen.next()将字符写入流而不是返回它
> make gen.next()将该字符附加到共享的BlockingQueue,并有一个专用的I / O线程从该队列中获取字符并打印它们.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读