我在学校遇到线程练习的问题,我们只是学习线程/同步,我有点迷失。
基本上我想要启动某个类的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对象。但我不太确定如何解决它。如果有人能以任何方式帮助我,那就太棒了:)。
答案 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
之前同步。