Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java线程,错误计数器_Java_Multithreading - Fatal编程技术网

Java线程,错误计数器

Java线程,错误计数器,java,multithreading,Java,Multithreading,我在代码段下面运行,得到了意想不到的行为。也许它是以正确的方式工作,但我需要让它以另一种方式工作。详情如下 import java.util.ArrayList; import java.util.List; public class TaskExample { public static void main(String[] args) throws InterruptedException { final PositionHolder holder = new PositionH

我在代码段下面运行,得到了意想不到的行为。也许它是以正确的方式工作,但我需要让它以另一种方式工作。详情如下

import java.util.ArrayList;
import java.util.List;

public class TaskExample {

public static void main(String[] args) throws InterruptedException {
    final PositionHolder holder = new PositionHolder();
    final List<Integer> data = new ArrayList<Integer>();
    List<Thread> threads = new ArrayList<Thread>();
    for (int i = 0; i < 20; i++) {
        holder.setPosition(i);
        Thread t = new Thread() {

            @Override
            public void run() {
                data.add(holder.getPosition());
            }
        };

        t.start();
        threads.add(t);
    }

    for (Thread thread : threads) {            
            thread.join();
        }

    for(int i : data){
        System.out.println(i);
    }
}
}

class PositionHolder {

    int position = 0;

    public void setPosition(int position) {
        this.position = position;
    }

    public int getPosition() {
        return this.position;
    }
}
import java.util.ArrayList;
导入java.util.List;
公共类任务示例{
公共静态void main(字符串[]args)引发InterruptedException{
最终位置保持架=新位置保持架();
最终列表数据=新的ArrayList();
List threads=new ArrayList();
对于(int i=0;i<20;i++){
固定位置(i);
线程t=新线程(){
@凌驾
公开募捐{
data.add(holder.getPosition());
}
};
t、 start();
添加(t);
}
对于(线程:线程){
thread.join();
}
for(int i:数据){
系统输出打印LN(i);
}
}
}
类职位持有者{
int位置=0;
公共无效设置位置(内部位置){
这个位置=位置;
}
public int getPosition(){
返回此位置;
}
}
我得到的结果是:

1012988665421616161819191919

为什么??我想得到:

1234。。。。。。二十

是否有导入此代码段的选项?

请尝试此代码;)

import java.util.ArrayList;
导入java.util.List;
公共类ogr
{
公共静态void main(字符串[]args)引发InterruptedException{
最终位置保持架=新位置保持架();
最终列表数据=新的ArrayList();
对于(int i=0;i<20;i++){
固定位置(i);
线程t=新线程(){
@凌驾
公开募捐{
data.add(holder.getPosition());
}
};
t、 start();
t、 join();
}
for(int i:数据){
系统输出打印LN(i);
}
}
}
类职位持有者
{
int位置=0;
公共无效设置位置(内部位置){
这个位置=位置;
}
public int getPosition(){
返回此位置;
}
}

无法保证holder.getPosition()将获得使用holder.setPosition(i)设置的相同位置值,因为getHolder调用是不同线程的一部分,并且由多个线程调用。这是因为您在所有线程中共享同一占位符。如果您希望获得所需的输出,我建议为每个线程使用不同的占位符实例

import java.util.ArrayList;
import java.util.List;

public class TaskExample {

public static void main(String[] args) throws InterruptedException {
     final List<Integer> data = new ArrayList<Integer>();
     List<Thread> threads = new ArrayList<Thread>();
     for (int i = 0; i < 20; i++) {
         // Create new instance
         final PositionHolder holder = new PositionHolder(i);
         Thread t = new Thread() {
             @Override
             public void run() {
                 data.add(holder.getPosition());
             }
         };
     t.start();
     threads.add(t);

     for (Thread thread : threads) {            
         thread.join();
     }

     for(int i : data){
         System.out.println(i);
     }
}

class PositionHolder {
    private int position = 0;

    public PositionHolder(int position) {
        this.position = position;
    }

    public int getPosition() {
        return this.position;
    }
}`
import java.util.ArrayList;
导入java.util.List;
公共类任务示例{
公共静态void main(字符串[]args)引发InterruptedException{
最终列表数据=新的ArrayList();
List threads=new ArrayList();
对于(int i=0;i<20;i++){
//创建新实例
最终定位器=新定位器(i);
线程t=新线程(){
@凌驾
公开募捐{
data.add(holder.getPosition());
}
};
t、 start();
添加(t);
对于(线程:线程){
thread.join();
}
for(int i:数据){
系统输出打印LN(i);
}
}
类职位持有者{
私有int位置=0;
公共职位持有者(内部职位){
这个位置=位置;
}
public int getPosition(){
返回此位置;
}
}`

如果没有像
join()这样的同步机制,就无法保证线程的执行顺序(请参阅Fincio提出的代码)


由于对所有线程使用相同的
PositionHolder
对象,因此,变量
position
会被启动的每个线程修改。尝试对对象而不是int执行相同操作可能会导致
ConcurrentAccessException
同样,每个螺纹都应该有自己的
PositionHolder
实例(如Saket提供的代码)但是,即使这样,也不能保证线程的执行顺序。

使用线程编程有时需要一些技巧来提高线程效率。显然,这并不是那么自然。例如,检查以下内容

import java.util.ArrayList;
import java.util.List;

public class ogr{
public static void main(String[] args) throws InterruptedException {
    ArrayList<PositionHolder> holders=new ArrayList<PositionHolder>();
    final PositionHolder holder = new PositionHolder();
    final List<Integer> data = new ArrayList<Integer>();
    for (int i = 0; i < 20; i++) {
        Thread t = new Thread() {

            @Override
            public void run() {
                data.add(getSetPosition());
            }
        };
        holders.add(holder)
        t.start();

    }
    for (Thread thread : threads) {            
        thread.join();
    }

    SortByPosition(holders); //you can implement this easy by sorting arraylist by their positions

    for (int i : data) {
        System.out.println(i);
    }
}
}

class PositionHolder{

static int staticPosition=0;
int position = 0;

public int synchronized getSetPosition() {
       this.position = staticPosition++;
       return position;
}

 //  public void setPosition(int position) {
 //      this.position = position;
 //  }

public int getPosition() {
    return this.position;
}
}
import java.util.ArrayList;
导入java.util.List;
公共类ogr{
公共静态void main(字符串[]args)引发InterruptedException{
ArrayList holders=新的ArrayList();
最终位置保持架=新位置保持架();
最终列表数据=新的ArrayList();
对于(int i=0;i<20;i++){
线程t=新线程(){
@凌驾
公开募捐{
data.add(getSetPosition());
}
};
持有人。添加(持有人)
t、 start();
}
对于(线程:线程){
thread.join();
}
SortByPosition(holders);//您可以通过按位置对arraylist进行排序来轻松实现这一点
for(int i:数据){
系统输出打印LN(i);
}
}
}
类职位持有者{
静态int staticPosition=0;
int位置=0;
public int synchronized getSetPosition(){
this.position=staticPosition++;
返回位置;
}
//公共无效设置位置(内部位置){
//这个位置=位置;
//  }
public int getPosition(){
返回此位置;
}
}

你需要同步对你的
数据的调用。如何做?当我添加:
公共同步的void run(){data.add(holder.getPosition();}我得到了:929931011451515161819191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191你需要一个接一个地同步运行线程,因为你不知道哪个1将首先获得处理器。@Mena-我认为,他的设计有缺陷,他必须在循环本身内同步,否则他可能会得到unpr
import java.util.ArrayList;
import java.util.List;

public class ogr{
public static void main(String[] args) throws InterruptedException {
    ArrayList<PositionHolder> holders=new ArrayList<PositionHolder>();
    final PositionHolder holder = new PositionHolder();
    final List<Integer> data = new ArrayList<Integer>();
    for (int i = 0; i < 20; i++) {
        Thread t = new Thread() {

            @Override
            public void run() {
                data.add(getSetPosition());
            }
        };
        holders.add(holder)
        t.start();

    }
    for (Thread thread : threads) {            
        thread.join();
    }

    SortByPosition(holders); //you can implement this easy by sorting arraylist by their positions

    for (int i : data) {
        System.out.println(i);
    }
}
}

class PositionHolder{

static int staticPosition=0;
int position = 0;

public int synchronized getSetPosition() {
       this.position = staticPosition++;
       return position;
}

 //  public void setPosition(int position) {
 //      this.position = position;
 //  }

public int getPosition() {
    return this.position;
}
}