多线程同步问题

时间:2015-09-17 19:33:20

标签: java multithreading synchronization

我在学校遇到线程练习的问题,我们只是学习线程/同步,我有点迷失。

基本上我想要启动某个类的4个线程。每个线程将运行25次并打印出数字1 --- 100。

这就是输出看起来像

的内容

主题1:1

主题3:2

主题4:3

主题2:4

主题3:100

但实际打印出来的是这样的。它很重要,但数字没有正确地吐出来。

主题1:1

主题3:1

主题4:5

主题2:6

主题3:7

主题3:8

主题1:9

主题2:10

主题4:10

主题3:100

这是我正在使用线程的类的代码

public class numberentrycreater implements Runnable
{
    final private int max = 100;
    private static int count = 1;
    private String createdBy;
    private SharedBuffer buffer;

    public numberentrycreater(String createdBy ){
        this.createdBy = createdBy;
    }

    public synchronized void  increment(NumberEntry ne){
        System.out.println(ne.getCreatedBy()+": " + ne.getValue());
        if(count<=max){
            count++;
        }
    }

    @Override
    public  void run()
    {
        for(int i=0; i<25; i++){
            if(count<=max){
                NumberEntry ne = new NumberEntry(count,createdBy);
                increment(ne);
                try
                {
                    Thread.sleep(100);
                } catch (InterruptedException e)
                {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
}

我认为问题在于创建NumberEntry对象。但我不太确定如何解决它。如果有人能以任何方式帮助我,那就太棒了:)。

2 个答案:

答案 0 :(得分:3)

这里的同步有点混乱,而且你会遇到很多竞争条件。

首先,您在进入synchronized方法之前创建了NumberEntry,因此没有理由认为多个线程不会获取相同的数字。

此外,同步方法实际上不会同步。 synchronized作为方法选项只是synchronized(this) { ... }的简写,this在这种情况下是可运行的,每个线程都是唯一的,所以他们都可以同时输入它。您需要同步他们共享的内容。尝试将块放在synchronized(numberentrycreater.class) { <method code> }的方法中。

编辑:

ControlAltDel建议使用next()同步方法而不是increment更优雅且不太可能出现问题。它仍然会遇到在错误的事情上(在撰写本文时)同步的问题。

答案 1 :(得分:1)

而不是你的增量函数

public synchronized void  increment(NumberEntry ne){

你应该有一个getNext函数

public synchronized int next() {

而不是在递增函数中打印出请求,您应该从run()块中将数据打印到SharedBuffer。如果SharedBuffer是线程安全的(如StringBuffer),那么您可以在不同步的情况下使用它。但是否则,在追加buffer之前同步。