我的线程并行运行吗?

sri*_*ram 3 java multithreading thread-safety

我有以下代码:

public class A extends Thread{

static List<String> a = new ArrayList<String>();

private String name;

public A(String name)
{
    this.name = name;
}

public void run() {
         synchronized (A.class) {
                    a.add(this.name);
                }     
    }

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

    for(int i=0;i<100;i++)
    {
        A s1 = new A("thread 1");
        A s2 = new A("thread 2");
        A s3 = new A("thread 3");

        s1.start();
        s2.start();
        s3.start();
    }
        Thread.sleep(1000);
        System.out.println("The message is " + a);

}

}
Run Code Online (Sandbox Code Playgroud)

我得到的输出是:

The message is [thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3, thread 1, thread 2, thread 3]
Run Code Online (Sandbox Code Playgroud)

从输出我不认为我的线程并行运行!

我应该在run方法中添加并发代码?

我在这里错过了什么吗?

T.J*_*der 8

您的线程只运行短的时间,因为run几乎立即终止.所以它们可能,但不太可能,它们同时运行.线程在其run方法返回时终止; 该run方法不是重复调用或类似的.

当然,由于你所做的一切run都是同步的A.class,即使它们同时运行,也会阻止其他人在共享列表中添加它们.

如果你想看到的实际线程同时运行的效果,你需要让他们继续做一些(或许在某种类型的循环run,或使用Thread.sleep与毫秒随机数),并取出同步(或有同步,看看它如何影响事情).但是,在执行此操作时,即使未在其他位置a.add同步,也要在调用时保持同步(最好是同步aA.class不是同步).(或将您的列表包装在Collections.synchronizedList.)

这是一个完整的示例,显示了实际上彼此重叠的线程:

import java.util.*;

public class ParallelExample extends Thread {

    static List<String> a = new ArrayList<String>();

    private String name;

    public ParallelExample(String name) {
        this.name = name;
    }

    public void run() {
        // Un-synchronized, random delay, just to let the threads
        // intermix.
        try {
            Thread.sleep((new Random()).nextInt(1000) + 500);
        }
        catch (Exception e) {
            // For this example I'm ignoring the InterruptedException
        }

        // Now add the name after that random delay
        synchronized(ParallelExample.class) {
            a.add(this.name);
        }
    }

    public static void main(String[] args) throws Exception {
        ParallelExample threads[] = new ParallelExample[10];

        // Start the threads
        for (int i = 0; i < threads.length; ++i) {
            threads[i] = new ParallelExample("thread " + i);
            threads[i].start();
        }

        // Don't use sleep here, use join
        try {
            for (int i = 0; i < threads.length; ++i) {
                threads[i].join();
            }
        }
        catch (Exception e) {
            // For this example I'm ignoring the InterruptedException
        }

        // Show results
        System.out.println("The message is " + a);
    }
}
Run Code Online (Sandbox Code Playgroud)

示例运行:

$ java ParallelExample 
The message is [thread 4, thread 3, thread 9, thread 7, thread 6, thread 2, thread 5, thread 1, thread 8, thread 0]