Почему Thread работает так?
Это не тред виноват, а замыкания.
Когда ты ссылаешься в лямбде на переменную - к ней обращение происходит по ссылке.
Вот и получилось, что на момент запуска значение i уже 2.
Решить эту проблему можно, если скопировать значение i в новую переменную вот так:
for (int i = 0; i < 2; i++)
{
    var i2 = i;
    Thread thread = new Thread(() =>
    {
        Console.WriteLine("main index: " + i2);
    });
    thread.Start();
}
потому что когда отработает Console.WriteLine то i уже станет 2. 

for (int i = 0; i < 2; i++)
{
    var index = i;
    var thread = new Thread(() =>
    {
        Console.WriteLine("main index: " + index);

    });
    thread.Start();
}

//main index: 1
//main index: 0