【问题标题】:Understanding threads and synchronization on a class that spawns the thread了解产生线程的类上的线程和同步
【发布时间】:2012-07-07 07:48:39
【问题描述】:

好的,有人可以在这里向我解释一下我的知识差距吗?

最初下面的示例试图同步一个实例方法,但后来意识到我生成了一个新实例,因此不会发生锁定。

所以我决定对类的静态方法进行锁定,希望线程能够按顺序运行,但仍然没有运气。任何人都可以解释我的方式的错误吗? (请容忍我,可能有更好的方法来做到这一点,它只是让理解正确,我是一名进入 Java 的 PHP 开发人员,我喜欢它 - 但我只有 2 天 ;-))

所以此时数字会以随机顺序打印出来。

第一类

package learningjava;


public class LearningJava {
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {

      ThreadCaller ob1 = new ThreadCaller("This is a test string 1");
      ThreadCaller ob2 = new ThreadCaller("This is a test string 2");
      ThreadCaller ob3 = new ThreadCaller("This is a test string 3");
      ThreadCaller ob4 = new ThreadCaller("This is a test string 4");
      ThreadCaller ob5 = new ThreadCaller("This is a test string 5");

      try {

           ob1.t.join();
           ob2.t.join();
           ob3.t.join();
           ob4.t.join();
           ob5.t.join();

      } catch (InterruptedException e) {

          System.out.println(e);

      }

    }    

}

2 级

package learningjava;

public class ThreadCaller implements Runnable {

    private String message;
    public Thread t;

    public ThreadCaller(String text) {
        message = text;
        t = new Thread(this);
        t.start();
    }

    public static synchronized void echo(String message) {
        System.out.println(message);
    }


    public void run() {
            ThreadCaller.echo(this.message);
    }

}

【问题讨论】:

    标签: java multithreading static synchronization


    【解决方案1】:

    谁能解释我的方法的错误?

    基本上,您所期待的订单根本无法保证。您连续在许多线程上调用start()...无法保证哪个线程将首先开始执行。您有一个静态同步方法这一事实仅意味着一次只有一个线程将执行该方法 - 它不能保证任何关于排序的事情。

    假设您有一条跑道,在跑道下方 100 米处有一个单车道大门。你开始比赛 - 哪个选手会先到达门口?

    幸运的是,这通常不是问题 - 如果值得启动多个线程来做某事,您通常并不关心它们的执行顺序。如果你这样做了,是时候重新检查你的设计了。

    【讨论】:

    • 波什!谢谢你。没有正确阅读这本书是我的错!现在感觉很愚蠢:-D
    【解决方案2】:

    线程的调度是不可预测的。

    你试图做的事情在某种程度上违背了它的目的,不是吗?

    如果您需要顺序,请按顺序执行或使用ExecutorService 调用它们。

    【讨论】:

    • 谢谢,刚刚投稿!
    【解决方案3】:

    无法以这种方式进行排序,因为您在加入之前已经启动了所有线程。

    您可以使用ExecurorService 来保持顺序,并创建一个线程池,然后在循环中将一个线程一个接一个地传递给池并执行它。

    代码中的其他方式不要在 Runnable 中启动线程,在 LearningJave 中启动它并在启动后立即加入它。

    Thread t1=new Thread(ob1);
       t1.start();
       t1.join();
    
       Thread t2=new Thread(ob2);
       t2.start();
       t2.join();
     ----
     -----
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-07
      • 2014-01-06
      • 1970-01-01
      • 1970-01-01
      • 2016-09-11
      • 1970-01-01
      相关资源
      最近更新 更多