Как решить проблему с DATA RACE?
Здесь два моментаgo list[i].Request(i)гарантировано инициирует поток, но вовсе не обязательно запускает и this.is_sync = true не исполняется. То есть может быть инициировано сколь угодно много горутин привязанных к одной Loc struct. Приоритет исполнения рутин в Go не детерменирован.Параметры в функцию передаются копированием значения, то есть вызов  func (this Loc) IsSync() boolпровоцирует полное копирование Loc, который может быть в работе. Что бы избежать копирования передавайте ссылкой. В рамках вашей архитетуры(что бы не менять код сильно) так должно работатьpackage main

import (
	"fmt"
	"sync/atomic"
	"time"
)

// наша структура
type Loc struct {
	is_sync *int32
	Value   int
}

// метод, который говорит, можно ли запускать метод Request
func (this *Loc) IsSync() bool {    //Передавайте параметр ссылкой, что бы избежать копирования
	return (atomic.LoadInt32(this.is_sync) != 0)
}

// основной запрос, который может длиться несколько секунд
func (this *Loc) Request(val int) {

	defer func() {
		atomic.StoreInt32(this.is_sync, 0)
		fmt.Println("End")
	}()

	fmt.Println("Request...")

	this.Value = val
	time.Sleep(time.Second)
}

var list []Loc

func init() {
	list = append(list, Loc{is_sync: new(int32)})
}

func main() {
	c := time.Tick(time.Second * 2)

	for range c {
		for i := 0; i < len(list); i++ {
			if list[i].IsSync() { // если ещё не пришло время, то пропускаем
				continue
			}
			atomic.StoreInt32(list[i].is_sync, 1) //флаг нужно выставить прямо здесь, а не дожидаясь исполнения рутины
			go list[i].Request(i)
		}
	}
}
Вам стоит посмотреть на подход с другой стороны. Для чего вам цикл? Сделайте его в каждой горутине Request(). По одной горутине на каждый объект Loc. Для управления (стартом/стопом между итерациями) используйте канал.
До остального дойдёте сами, либо не дойдёте - как знать:)