Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/323.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 未为Runnable类型的类任务执行Run方法_Java_Multithreading - Fatal编程技术网

Java 未为Runnable类型的类任务执行Run方法

Java 未为Runnable类型的类任务执行Run方法,java,multithreading,Java,Multithreading,我是多线程新手,在下面给出的示例中,我尝试将所有任务中的a和b的值求和,并将其保存在finalAnswer变量中。但不知何故,我的跑步方法没有被触发。请告诉我遗漏了什么。可能会有很多愚蠢的错误,但也要为此道歉 package MultiThreading; import java.util.LinkedList; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concur

我是多线程新手,在下面给出的示例中,我尝试将所有任务中的a和b的值求和,并将其保存在finalAnswer变量中。但不知何故,我的跑步方法没有被触发。请告诉我遗漏了什么。可能会有很多愚蠢的错误,但也要为此道歉

package MultiThreading;

import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Executor {

static List<Task> list = new LinkedList<Task>();

public static void main(String[] args) {
    Task t1 = new Task(1, 2, "u1");
    Task t2 = new Task(3, 4, "u2");
    Task t3 = new Task(5, 6, "u3");
    Task t4 = new Task(7, 8, "u1");
    Task t5 = new Task(9, 10, "u2");
    Task t6 = new Task(11, 12, "u3");
    Task t7 = new Task(13, 14, "u1");
    Task t8 = new Task(15, 16, "u2");
    Task t9 = new Task(17, 18, "u3");

    list.add(t1);
    list.add(t2);
    list.add(t3);
    list.add(t4);
    list.add(t5);
    list.add(t6);
    list.add(t7);
    list.add(t8);
    list.add(t8);

    ExecutorService executor = Executors.newFixedThreadPool(5);
    list.stream().forEach(x -> executor.submit(() -> new Task(x.a, x.b, x.userName)));

    System.out.println(" finalAnswer " + Task.finalAnswer);

}

static class Task implements Runnable {

    int a;
    int b;
    String userName;

    public Task(int a, int b, String userName) {
        this.a = a;
        this.b = b;
        this.userName = userName;
        System.out.println(" a " + a + " b " + b + " userName " + userName);
    }

    static Integer finalAnswer = 0;

    @Override
    public void run() {
        finalAnswer += (a + b);
        System.out.println(" Thread info " + Thread.currentThread().getName());
    }

}
包多线程;
导入java.util.LinkedList;
导入java.util.List;
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
公共类执行者{
静态列表=新建LinkedList();
公共静态void main(字符串[]args){
任务t1=新任务(1,2,“u1”);
任务t2=新任务(3,4,“u2”);
任务t3=新任务(5,6,“u3”);
任务t4=新任务(7,8,“u1”);
任务t5=新任务(9,10,“u2”);
任务t6=新任务(11,12,“u3”);
任务t7=新任务(13,14,“u1”);
任务t8=新任务(15,16,“u2”);
任务t9=新任务(17,18,“u3”);
列表。添加(t1);
增加(t2);
增加(t3);
列表。添加(t4);
列表。添加(t5);
列表。添加(t6);
增加(t7);
增加(t8);
增加(t8);
ExecutorService executor=Executors.newFixedThreadPool(5);
list.stream().forEach(x->executor.submit(()->新任务(x.a,x.b,x.userName));
System.out.println(“finalAnswer”+Task.finalAnswer);
}
静态类任务实现可运行{
INTA;
int b;
字符串用户名;
公共任务(int a、int b、字符串用户名){
这个a=a;
这个.b=b;
this.userName=用户名;
System.out.println(“a”+a+“b”+b+“用户名”+用户名);
}
静态整数finalAnswer=0;
@凌驾
公开募捐{
最终答案+=(a+b);
System.out.println(“线程信息”+Thread.currentThread().getName());
}
}
}


请建议。

您可以在for循环中使用
executor.submit(task)
,这会触发任务在不同线程中运行。要查看它是否正在运行,您需要在主线程上等待,然后再使用
thread.currentThread().join
或某种睡眠(someLongPeriod)打印finalAnswer


这样,在主线程等待时,单个任务在工作线程中运行。一旦执行完毕,您就可以打印finalAnswer了,您可以在for循环中使用
executor.submit(task)
,这会触发任务在不同的线程中运行。要查看它是否正在运行,您需要在主线程上等待,然后再使用
thread.currentThread().join
或某种睡眠(someLongPeriod)打印finalAnswer

这样,在主线程等待时,单个任务在工作线程中运行。执行完毕后,您可以打印finalAnswer这一行:

list.stream().forEach(x -> executor.submit(() -> new Task(x.a, x.b, x.userName)));
不是我想你想的那样

这是提交一个runnable,它只是创建一个新任务。实际上:

list.stream().forEach(x -> executor.submit(new Runnable() {
  @Override public void run() {
    new Task(x.a, x.b, x.userName);
  }
});
它实际上并不运行
Task.run()
方法

因此,你可以:

  • 直接调用
    run()
    ()->新任务(x.a、x.b、x.userName)。run()
  • 提交
    新任务
    执行者。提交(新任务(x.a、x.b、x.userName))
  • 但是当
    任务
    实现
    可运行
    executor.submit(x)
    (或者使用
    list.forEach(executor::submit)
    )时,为什么还要创建新的
    任务
但是,您在
finalAnswer
变量更新的原子性和可见性方面存在问题

  • finalAnswer+=(a+b)不是原子的:它是
    finalAnswer=finalAnswer+(a+b)
    。在读取和写入之间,没有任何内容阻止另一个线程写入到
    finalAnswer
  • System.out.println(“finalAnswer”+Task.finalAnswer)
    不保证看到
    finalAnswer
    的更新值
最简单的解决方案是相互同步对
finalAnswer
变量的访问:

synchronized (Task.class) {
  System.out.println(" finalAnswer " + Task.finalAnswer);
}

//

synchronized (Task.class) {
  finalAnswer += (a * b);
}
还存在其他解决方案,例如使用
AtomicInteger

但一般来说,executor框架的使用非常糟糕:最好向executor提交
Callable
,并将所有结果累加到主线程中。

这一行:

list.stream().forEach(x -> executor.submit(() -> new Task(x.a, x.b, x.userName)));
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;

public class Main {
    static AtomicInteger finalAnswer = new AtomicInteger(0) ;
    static List<Task> list = new ArrayList<>();


    public static void main(String[] args) {

        list.add(new Task(1, 2, "u1"));
        list.add(new Task(3, 4, "u2"));
        list.add(new Task(5, 6, "u3"));
        list.add(new Task(7, 8, "u1"));
        list.add(new Task(9, 10, "u2"));
        list.add(new Task(11, 12, "u3"));
        list.add(new Task(13, 14, "u1"));
        list.add(new Task(15, 16, "u2"));
        list.add(new Task(17, 18, "u3"));

        ExecutorService executor = Executors.newFixedThreadPool(5);
        list.forEach(executor::submit);
        executor.shutdown();
        while (!executor.isTerminated()) {}
        System.out.println(" finalAnswer " + Main.finalAnswer);

    }
}

class Task implements Runnable {
    int a;
    int b;
    String userName;

    Task(int a, int b, String userName) {
        this.a = a;
        this.b = b;
        this.userName = userName;
        System.out.println(" a " + a + " b " + b + " userName " + userName);
    }

    @Override
    public void run() {
        Main.finalAnswer.getAndAdd(a + b);
        System.out.println(" Thread info " + Thread.currentThread().getName());
    }
}
不是我想你想的那样

这是提交一个runnable,它只是创建一个新任务。实际上:

list.stream().forEach(x -> executor.submit(new Runnable() {
  @Override public void run() {
    new Task(x.a, x.b, x.userName);
  }
});
它实际上并不运行
Task.run()
方法

因此,你可以:

  • 直接调用
    run()
    ()->新任务(x.a、x.b、x.userName)。run()
  • 提交
    新任务
    执行者。提交(新任务(x.a、x.b、x.userName))
  • 但是当
    任务
    实现
    可运行
    executor.submit(x)
    (或者使用
    list.forEach(executor::submit)
    )时,为什么还要创建新的
    任务
但是,您在
finalAnswer
变量更新的原子性和可见性方面存在问题

  • finalAnswer+=(a+b)不是原子的:它是
    finalAnswer=finalAnswer+(a+b)
    。在读取和写入之间,没有任何内容阻止另一个线程写入到
    finalAnswer
  • System.out.println(“finalAnswer”+Task.finalAnswer)
    不保证看到
    finalAnswer
    的更新值
最简单的解决方案是相互同步对
finalAnswer
变量的访问:

synchronized (Task.class) {
  System.out.println(" finalAnswer " + Task.finalAnswer);
}

//

synchronized (Task.class) {
  finalAnswer += (a * b);
}
还存在其他解决方案,例如使用
AtomicInteger

但一般来说,executor框架的使用非常糟糕:最好向executor提交
Callable
,并将所有结果累加到主线程中。

导入java.util.ArrayList;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;

public class Main {
    static AtomicInteger finalAnswer = new AtomicInteger(0) ;
    static List<Task> list = new ArrayList<>();


    public static void main(String[] args) {

        list.add(new Task(1, 2, "u1"));
        list.add(new Task(3, 4, "u2"));
        list.add(new Task(5, 6, "u3"));
        list.add(new Task(7, 8, "u1"));
        list.add(new Task(9, 10, "u2"));
        list.add(new Task(11, 12, "u3"));
        list.add(new Task(13, 14, "u1"));
        list.add(new Task(15, 16, "u2"));
        list.add(new Task(17, 18, "u3"));

        ExecutorService executor = Executors.newFixedThreadPool(5);
        list.forEach(executor::submit);
        executor.shutdown();
        while (!executor.isTerminated()) {}
        System.out.println(" finalAnswer " + Main.finalAnswer);

    }
}

class Task implements Runnable {
    int a;
    int b;
    String userName;

    Task(int a, int b, String userName) {
        this.a = a;
        this.b = b;
        this.userName = userName;
        System.out.println(" a " + a + " b " + b + " userName " + userName);
    }

    @Override
    public void run() {
        Main.finalAnswer.getAndAdd(a + b);
        System.out.println(" Thread info " + Thread.currentThread().getName());
    }
}
导入java.util.LinkedList; 导入java.util.List; 导入java.util.Map; 导入java.util.con