如果从类扩展线程类创建多个线程,方法是否需要进行同步?

时间:2015-01-03 14:52:16

标签: java

以下是我的代码

class ExtendsThread extends Thread {

   private int counter = 0;
   /* should I need to make Display synchronize ?*/
   public void Display() {
       counter++;
     System.out.println("ExtendsThread : Counter : " + counter);
   } 
   public void run() {
     Display();
   }
 }

public class MyMain{

   public static void main(String args[]) throws Exception {

//Creating new instance for every thread access.
     ExtendsThread tc1 = new ExtendsThread();
     tc1.start();
     Thread.sleep(1000); // Waiting for 1 second before starting next thread
     ExtendsThread tc2 = new ExtendsThread();
     tc2.start();
     Thread.sleep(1000); // Waiting for 1 second before starting next thread
     ExtendsThread tc3 = new ExtendsThread();
     tc3.start();
}

output is :

ExtendsThread : Counter : 1
ExtendsThread : Counter : 1
ExtendsThread : Counter : 1

我读到当你扩展Thread类时,你的每个线程都会创建唯一的对象并与之关联,因此counter始终是一个。

现在我的问题是我需要同步Display方法吗? AS计数器始终为1,因为它是单独的对象,因此我们不需要使用同步。 这是对的吗?

4 个答案:

答案 0 :(得分:1)

您可以同步对静态计数器的访问,或者您可以使用AtomicInteger,它将为您处理线程安全...

class ExtendsThread extends Thread {
    private static final AtomicInteger counter = new AtomicInteger(0);
    public void Display() {
       System.out.println("ExtendsThread : Counter : " + counter.incrementAndGet());
    } 
    public void run() {
        Display();
    }
 }

现在的方式是,counter的每个实例都有一个ExtendsThread实例。如果您希望在特定类的所有实例之间共享counter(或任何字段),则必须使它们static。由于您将有多个线程访问现在的静态计数器,因此您必须控制对它们的访问,以便它们不会导致竞争条件。这就是AtomicInteger的用武之地 - 它为您处理所有这些。

答案 1 :(得分:1)

在您的示例中,每个线程都有自己的counter变量副本,因此不需要同步。如果变量是在线程之间共享的,那么应该有同步。

答案 2 :(得分:0)

synchronize用于防止两个线程同时执行该方法。您需要使用同步,但这里的关键因素是您还需要创建变量static,因此该类的所有实例共享相同的变量。

答案 3 :(得分:0)

在您的示例中,获取不同值的唯一方法是将变量设置为静态,如下所示:

private static int counter = 0;

如果您不希望线程保持有问题,建议使用同步方法。