When two threads try to access the same resources at exactly the same time how does the computer decide which one gets the resource, or is it just decided at random?
On a single-processor system, it is impossible for two threads to access the same location simultaneously. Rather, if the threads access the same data outside of a critical section, it's possible for their execution to become interleaved, in which case the access order is undefined. Execution is concurrent and you might call the result "random", in that nothing obvious affects the choice of one thread's code over another's. Of course, the scheduler is making the choice somehow, but it's fairly opaque in terms of ordering for access to thread-shared memory.
In multiprocessor/multicore/distributed applications, the notion of ordering is a little hazier. We can define the happens-before partial relation based on causation of signals and use this to define time stamps that can be used for coordinating events across sites. Unrelated events are called concurrent, and any processes which care about the order of concurrent events need to agree amongst themselves. Consistency is a well-studied problem in shared-memory distributed systems. If sites request access to shared memory over some medium (bus, interconnect, etc.) then the medium access protocol will, in an opaque fashion, determine which thread gets access first. Like scheduling, the result here may appear "random", since different decisions can be made on different executions.
a "race condition" is actually a more technical/specialized term than the sense you are using in a generic way, it does not really simply mean that two threads are accessing the same resource at the same time. it is in general used to refer to subtle programming defects where the results of parallel thread processing can unintentionally vary based on thread execution order, when the intention is that there is not a variation. in other words imagine two threads A, B that do some same "operation". and the results of that "operation" are "different" when thread A runs before thread B versus when thread B runs before thread A.
in a multithreaded system one cannot assume a particular thread execution order unless it is fixed by thread ordering mechanisms (eg say a multithreading synchronization system like a semaphore etcetera).