Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/8.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_Java Threads - Fatal编程技术网

Java 使用线程修改对象

Java 使用线程修改对象,java,java-threads,Java,Java Threads,我是新手。我想让两个线程将一个整数增加到某个值。因为int类型是不可变的,所以我切换到原子整数。我还尝试将int封装到类中,但也没有成功。我还尝试了静态/易失性int,但没有成功。我还尝试使用公平政策。主要问题是“counterObj”没有正确递增,即使它被注入到两个线程中,它仍然被设置为0 我预期的跑步行为: thread value thread 0 0 thread 1 1 thread 0 2 ... 到目前为止我写的是: import java.u

我是新手。我想让两个线程将一个整数增加到某个值。因为int类型是不可变的,所以我切换到原子整数。我还尝试将int封装到类中,但也没有成功。我还尝试了静态/易失性int,但没有成功。我还尝试使用公平政策。主要问题是“counterObj”没有正确递增,即使它被注入到两个线程中,它仍然被设置为0

我预期的跑步行为:

thread       value
thread 0     0
thread 1     1
thread 0     2
...
到目前为止我写的是:

import java.util.concurrent.atomic.AtomicInteger;

public class Application {
    public static void main(String[] args) {
        Application app = new Application();
        try {
            app.launch();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private void launch() throws InterruptedException {
        int increments = 100;
        AtomicInteger counterObj = new AtomicInteger(0);
        CounterThread th1 = new CounterThread("1", counterObj, increments);
        CounterThread th2 = new CounterThread("2", counterObj, increments);
        th1.start();
        th2.start();


        System.out.println(counterObj.get());

    }


}

导入java.util.concurrent.AtomicInteger;
公共类计数器线程实现可运行{
私有最终字符串threadID;
私有原子;
私有内边界;
公共计数器线程(字符串threadID,原子整数计数器,int-bound){
this.threadID=threadID;
this.counterObj=计数器;
this.bound=bound;
}
@凌驾
公共同步的无效运行(){
while(counterObj.get()

干杯

我认为您的程序在线程有机会做任何事情之前就已经退出了(可能是由于启动和连接的顺序。我会将您的线程启动逻辑移到main(或launch)方法中。如下所示

Thread thread1 = new Thread(new MyCounterRunnable("1", counterObj, increments));
Thread thread2 = new Thread(new MyCounterRunnable("2", counterObj, increments));
然后,在main中,您需要在启动线程后调用join…如下所示:

thread1.start(); // starts first thread.
thread2.start(); // starts second thread.

thread1.join(); // don't let main exit until thread 1 is done.
thread2.join(); // don't let main exit until thread 2 is done.

我认为你的程序在你的线程有机会做任何事情之前就已经退出了(可能是因为你的启动和连接的顺序。我会将你的线程启动逻辑移到你的main(或launch)方法中。如下所示

Thread thread1 = new Thread(new MyCounterRunnable("1", counterObj, increments));
Thread thread2 = new Thread(new MyCounterRunnable("2", counterObj, increments));
然后,在main中,您需要在启动线程后调用join…如下所示:

thread1.start(); // starts first thread.
thread2.start(); // starts second thread.

thread1.join(); // don't let main exit until thread 1 is done.
thread2.join(); // don't let main exit until thread 2 is done.

您真正想要的是一次只让一个线程增加一个int。 int变量是同步块中所需的资源,因此不同的线程可以一次递增一个。 这可以单独使用syncrhonize来完成。 免责声明:我没有运行代码,因此它可能会有一些打字错误或异常从应用程序类中删除

public class Application {

  private int theVar = 0;
  private int increments = 100;

  public static void main(String[] args) {
    Application app = new Application();
    try {
        app.launch();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
  }

  public synchronized addOne(){
    this.theVar++;
  }

  private void launch() throws InterruptedException {
    Runnable counter1 = new Counter(this, increments), counter2 = new Counter(this, increments);
    Thread t1 = new Thread(counter1);
    Thread t2 = new Thread(counter2);
    t1.start();
    t2.start();
  }
}
柜台

public class Counter implements Runnable{
  private Application app;
  int rounds = -1;

  public Counter(Application app, rounds){
    this.app = app;
    this.rounds = rounds;
  }
  public void run(){
    while(int i=0; i<rounds; i++){
        this.app.addOne();
    }
  }
}
公共类计数器实现可运行{
私人应用程序;
整数回合=-1;
公共柜台(应用程序、轮次){
this.app=app;
这个。轮数=轮数;
}
公开募捐{

而(inti=0;i您真正想要的是一次只让一个线程增加一个int。 int变量是同步块中所需的资源,因此不同的线程可以一次递增一个。 这可以单独使用syncrhonize来完成。 免责声明:我没有运行代码,因此它可能会有一些打字错误或异常从应用程序类中删除

public class Application {

  private int theVar = 0;
  private int increments = 100;

  public static void main(String[] args) {
    Application app = new Application();
    try {
        app.launch();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
  }

  public synchronized addOne(){
    this.theVar++;
  }

  private void launch() throws InterruptedException {
    Runnable counter1 = new Counter(this, increments), counter2 = new Counter(this, increments);
    Thread t1 = new Thread(counter1);
    Thread t2 = new Thread(counter2);
    t1.start();
    t2.start();
  }
}
柜台

public class Counter implements Runnable{
  private Application app;
  int rounds = -1;

  public Counter(Application app, rounds){
    this.app = app;
    this.rounds = rounds;
  }
  public void run(){
    while(int i=0; i<rounds; i++){
        this.app.addOne();
    }
  }
}
公共类计数器实现可运行{
私人应用程序;
整数回合=-1;
公共柜台(应用程序、轮次){
this.app=app;
这个。轮数=轮数;
}
公开募捐{

虽然(inti=0;i我已经包含了对AtomicInteger的双重检查,但这似乎是您一直试图实现的

import java.util.concurrent.atomic.AtomicInteger;

public class DualCounters{

    public static void main(String[] args) throws Exception{
        AtomicInteger i = new AtomicInteger(0);
        int bounds = 3;

        Thread a = new Thread(()->{
            int last = 0;
            while(i.get()<bounds){
                synchronized(i){
                    if(i.get()<bounds){
                        last = i.getAndIncrement();
                    }
                }
            }
            System.out.println("a last " + last);
        });

        Thread b = new Thread(()->{
            int last = 0;
            while(i.get()<bounds){
                synchronized(i){
                    if(i.get()<bounds){
                        last = i.getAndIncrement();
                    }
                }
            }
            System.out.println("b last " + last);
        });

        a.start();
        b.start();

        a.join();
        b.join();

        System.out.println(i.get() + " afterwards");

    }
}

我已经包含了对AtomicInteger的双重检查,这似乎是您一直试图实现的

import java.util.concurrent.atomic.AtomicInteger;

public class DualCounters{

    public static void main(String[] args) throws Exception{
        AtomicInteger i = new AtomicInteger(0);
        int bounds = 3;

        Thread a = new Thread(()->{
            int last = 0;
            while(i.get()<bounds){
                synchronized(i){
                    if(i.get()<bounds){
                        last = i.getAndIncrement();
                    }
                }
            }
            System.out.println("a last " + last);
        });

        Thread b = new Thread(()->{
            int last = 0;
            while(i.get()<bounds){
                synchronized(i){
                    if(i.get()<bounds){
                        last = i.getAndIncrement();
                    }
                }
            }
            System.out.println("b last " + last);
        });

        a.start();
        b.start();

        a.join();
        b.join();

        System.out.println(i.get() + " afterwards");

    }
}

AtomicInteger
负责原子性本身,因此您不需要使用
synchronized
——但前提是您遵守规则,并在一次调用中执行原子操作

您没有做到这一点,因为您调用了
counterObj.get()
,然后根据结果
counterObj.incrementAndGet()
。您需要避免这种情况,因为您希望检查和更新是同一工作原子块的一部分

您可以通过以下方式接近:

while(counterObj.incrementAndGet() < bound) {} ;
while(counterObj.incrementAndGet()
但这将始终至少增加一次,这可能太多了

稍微涉及:

IntUnaryOperator incrementWithLimit = x -> 
   ( x < bound ? x + 1 : x );

while(counterObj.updateAndGet(incrementWithLimit) < bound) {};
IntUnaryOperator incrementWithLimit=x->
(x

也就是说,我们已经创建了一个函数,它只在一个数小于
界值时递增一个数,我们告诉
AtomicInteger
应用这个函数。

AtomicInteger
处理原子性本身,所以你不需要使用
同步的
——但前提是你要遵守规则,并且在一个电话

您没有做到这一点,因为您调用了
counterObj.get()
,然后根据结果
counterObj.incrementAndGet()
。您需要避免这种情况,因为您希望检查和更新是同一工作原子块的一部分

您可以通过以下方式接近:

while(counterObj.incrementAndGet() < bound) {} ;
while(counterObj.incrementAndGet()
但这将始终至少增加一次,这可能太多了

稍微涉及:

IntUnaryOperator incrementWithLimit = x -> 
   ( x < bound ? x + 1 : x );

while(counterObj.updateAndGet(incrementWithLimit) < bound) {};
IntUnaryOperator incrementWithLimit=x->
(x

也就是说,我们创建了一个函数,该函数仅在数值小于
界限时递增数值,我们告诉
AtomicInteger
应用该函数。

您的代码有几个问题:

方法仅在线程已启动时有效,否则它将不起任何作用。因此,您必须对代码重新排序,但如果您只是将join方法移动到start之后,当通过调用CounterThread.start启动第一个线程时,主线程将等待启动的线程完成,并在中阻塞rong>Thread.join方法,只有这样才能继续启动