首页 \ 问答 \ 简单的Java多线程测试不起作用(Simple Java multihreading test not working)

简单的Java多线程测试不起作用(Simple Java multihreading test not working)

我写了一些java代码,使用while循环可以在1秒内增加一个值。

然后我尝试使用4个线程在1秒内尽可能多地增加四个值。 我期待有四个线程,与简单循环相比,我将获得四倍的值。

代码如下:

package threadTest;

public class ThreadTestMain {

public static void main(String[] args) {

    long end_time = 0;
    long value = 0;
    long runtime = 0;

    long start_time = System.currentTimeMillis();
    while (runtime<=1000) {
        value++;
        runtime = System.currentTimeMillis() - start_time;
    }

    System.out.println(value);
    end_time = System.currentTimeMillis();
    System.out.println("DEBUG-> Time should be 1sec : " + (end_time - start_time));

    SeperateExecution myObject = new SeperateExecution(0);
    SeperateExecution myObject2 = new SeperateExecution(0);
    SeperateExecution myObject3 = new SeperateExecution(0);
    SeperateExecution myObject4 = new SeperateExecution(0);

    Thread worker1 = new Thread(myObject,"worker1");
    Thread worker2 = new Thread(myObject2,"worker2");
    Thread worker3 = new Thread(myObject3,"worker3");
    Thread worker4 = new Thread(myObject4,"worker4");

    worker1.start();worker2.start();worker3.start();worker4.start();
}

}

package threadTest;

//import java.util.concurrent.atomic.AtomicLong;

public class SeperateExecution implements Runnable {
private long value = 0;
//private AtomicLong value = null;
private long start_time = 0;

public SeperateExecution (long p_val)
{
    this.value = p_val;
    //this.value = new AtomicLong(p_val);
    //this.start_time = p_st;
}

@Override
public void run(){
    long runtime = 0;
    this.start_time = System.currentTimeMillis();
    while (runtime<=1000) {
        //value.incrementAndGet();
        value++;
        runtime = System.currentTimeMillis() - start_time;
    }
    System.out.println(Thread.currentThread().getName() + " DONE " + value + 
            " Thread Exection Time " + (System.currentTimeMillis()- start_time));
}
}

代码输出如下:

52266551
DEBUG-> Time should be 1sec : 1001
worker1 DONE 13364059 Thread Exection Time 1001
worker2 DONE 13744972 Thread Exection Time 1001
worker4 DONE 11652084 Thread Exection Time 1001
worker3 DONE 13605645 Thread Exection Time 1001

有人可以帮助我理解为什么多线程值总和一个小于正常while循环的值?

一个类比,以帮助理解我的问题:如果一个工人一天可以挖一个洞,那么四个工人可以一天挖四个洞。

谢谢


I wrote some java code that would increase a value as much it could in 1 second using a while loop.

I then tried increasing four values as much as it could in 1 second using 4 threads. I was expecting that with four threads I would get to four times the value as compared with the simple loop.

Code is as follows:

package threadTest;

public class ThreadTestMain {

public static void main(String[] args) {

    long end_time = 0;
    long value = 0;
    long runtime = 0;

    long start_time = System.currentTimeMillis();
    while (runtime<=1000) {
        value++;
        runtime = System.currentTimeMillis() - start_time;
    }

    System.out.println(value);
    end_time = System.currentTimeMillis();
    System.out.println("DEBUG-> Time should be 1sec : " + (end_time - start_time));

    SeperateExecution myObject = new SeperateExecution(0);
    SeperateExecution myObject2 = new SeperateExecution(0);
    SeperateExecution myObject3 = new SeperateExecution(0);
    SeperateExecution myObject4 = new SeperateExecution(0);

    Thread worker1 = new Thread(myObject,"worker1");
    Thread worker2 = new Thread(myObject2,"worker2");
    Thread worker3 = new Thread(myObject3,"worker3");
    Thread worker4 = new Thread(myObject4,"worker4");

    worker1.start();worker2.start();worker3.start();worker4.start();
}

}

and

package threadTest;

//import java.util.concurrent.atomic.AtomicLong;

public class SeperateExecution implements Runnable {
private long value = 0;
//private AtomicLong value = null;
private long start_time = 0;

public SeperateExecution (long p_val)
{
    this.value = p_val;
    //this.value = new AtomicLong(p_val);
    //this.start_time = p_st;
}

@Override
public void run(){
    long runtime = 0;
    this.start_time = System.currentTimeMillis();
    while (runtime<=1000) {
        //value.incrementAndGet();
        value++;
        runtime = System.currentTimeMillis() - start_time;
    }
    System.out.println(Thread.currentThread().getName() + " DONE " + value + 
            " Thread Exection Time " + (System.currentTimeMillis()- start_time));
}
}

The code output is as follows:

52266551
DEBUG-> Time should be 1sec : 1001
worker1 DONE 13364059 Thread Exection Time 1001
worker2 DONE 13744972 Thread Exection Time 1001
worker4 DONE 11652084 Thread Exection Time 1001
worker3 DONE 13605645 Thread Exection Time 1001

Can someone please help me understand why the multithreaded values sum up to a value less that the normal while loop?

An analogy to help understand my question: If one worker can dig one hole in a day then surly four workers can dig four holes in a day.

Thanks


原文:https://stackoverflow.com/questions/24069210
更新时间:2023-09-21 17:09

最满意答案

我终于找到了一个解决方案,其中包括编写自定义的javascript组件 。 我也尝试使用CustomLayout实现这一点,但从未执行过facebook javascript调用。

AutoLoginView类:

public class AutoLoginView extends VerticalLayout
{  
  public AutoLoginView()
  {
    addComponent(new AutoLoginComponent());
  }
}

AutoLoginComponent类:

@JavaScript({ "https://connect.facebook.net/en_US/all.js", "AutoLoginComponent-connector-v3.js" })
public class AutoLoginComponent extends AbstractJavaScriptComponent
{
  public AutoLoginComponent()
  {
    addFunction("reportLoginStatusInfo", new JavaScriptFunction() {
      @Override
      public void call(final JsonArray arguments) throws JsonException
      {
        handleLoginStatusInfo(arguments);
      }
    });
  }

  private void handleLoginStatusInfo(JsonArray arguments)
  {
    String status= arguments.get(0).asString();

    if ("connected".equals(status))
    {
      String user_id = arguments.get(1).asString();
      String access_code = arguments.get(2).asString();
    }
  }
}

AutoLoginComponent-connector-v3.js( 此处您必须调整包名称和应用ID ):

window.package_AutoLoginComponent = function()
{
    FB.init(
    {
      appId      : '<your-app-id>',
      status     : true,
      xfbml      : false,
      version    : 'v2.4'
    });

    var connector = this;

    FB.getLoginStatus(function(response) 
    {
      if (response.status === 'connected')
      {
          connector.reportLoginStatusInfo(response.status, response.authResponse.userID, response.authResponse.accessToken);
      }
      else
      {
          connector.reportLoginStatusInfo(response.status, null, null);   
      }
    });
};

I finally figured out a solution, which involved writing a custom javascript component. I also tried to achieve this with CustomLayout, but that never executed the facebook javascript calls.

The AutoLoginView class:

public class AutoLoginView extends VerticalLayout
{  
  public AutoLoginView()
  {
    addComponent(new AutoLoginComponent());
  }
}

The AutoLoginComponent class:

@JavaScript({ "https://connect.facebook.net/en_US/all.js", "AutoLoginComponent-connector-v3.js" })
public class AutoLoginComponent extends AbstractJavaScriptComponent
{
  public AutoLoginComponent()
  {
    addFunction("reportLoginStatusInfo", new JavaScriptFunction() {
      @Override
      public void call(final JsonArray arguments) throws JsonException
      {
        handleLoginStatusInfo(arguments);
      }
    });
  }

  private void handleLoginStatusInfo(JsonArray arguments)
  {
    String status= arguments.get(0).asString();

    if ("connected".equals(status))
    {
      String user_id = arguments.get(1).asString();
      String access_code = arguments.get(2).asString();
    }
  }
}

The AutoLoginComponent-connector-v3.js (here you will have to adjust your package name and your app id):

window.package_AutoLoginComponent = function()
{
    FB.init(
    {
      appId      : '<your-app-id>',
      status     : true,
      xfbml      : false,
      version    : 'v2.4'
    });

    var connector = this;

    FB.getLoginStatus(function(response) 
    {
      if (response.status === 'connected')
      {
          connector.reportLoginStatusInfo(response.status, response.authResponse.userID, response.authResponse.accessToken);
      }
      else
      {
          connector.reportLoginStatusInfo(response.status, null, null);   
      }
    });
};

相关问答

更多
  • 我终于找到了一个解决方案,其中包括编写自定义的javascript组件 。 我也尝试使用CustomLayout实现这一点,但从未执行过facebook javascript调用。 AutoLoginView类: public class AutoLoginView extends VerticalLayout { public AutoLoginView() { addComponent(new AutoLoginComponent()); } } AutoLoginCompon ...
  • 当然,您只需将范围user_likes添加到Facebook登录按钮即可。 您可以在此处阅读有关facebook登录按钮和范围属性的更多信息 既然您可以访问用户喜欢的内容,那么您可以检查用户是否喜欢您的网页,如果是,那么只需将用户重定向到您的网站,如果没有,只需提示他喜欢您的网页,然后他就可以访问您的其余部分网站。 这里有一些代码,使用Facebook Javascript SDK