С филосовской точки зрения всё равно потоки не стартуют одновременно, так как процессор-то один.
Но с точки зрения программирования можно предложить следующее решение с потоками-стартерами рабочих потоков. 
class Program
{
static List<Thread> threads = new List<Thread>();   // Список потоков
static int threadCount = 10;                        // Число потоков
static ManualResetEvent startEvent = new ManualResetEvent(false);   // Событие для старта рабочих потоков
static volatile int starterCount = 0;               // Счётчик запущенных потоков. volatile показывает, что переменная будет изменяться в различных потоках и её не надо оптимизировать
static object LockObject = new object();            // Блокировка для изменения переменной starterCount
static void Main(string[] args)
{
    // Создаём пул потоков
    for (int i = 0; i < threadCount; i++)
    {
        Thread thread = new Thread(Work);
        threads.Add(thread);
    }
    // На старт — запускаем стартовые потоки и ждём их запуска
    foreach (var thread in threads)
        new Thread(Starting).Start(thread);
    while (starterCount < threadCount) Thread.Sleep(1);
    // Внимание — к этому моменту все стартовые потоки запустились и ожидают на WaitOne()
    Thread.Sleep(100);
    // Марш — установка события отпускает приостановленные потоки
    startEvent.Set();
    while (true) ;
}
static void Starting(object paramThread)
{
    lock (LockObject)
    {
        starterCount++;
    }
    startEvent.WaitOne();
    (paramThread as Thread).Start();            
}
static void Work()
{
    return;
}
}