I feel like your misunderstanding the purposes of WebDriver, Grid and a multi-threaded environment.
Selenium WebDriver is just a test framework that kicks off tests onto a browser. It uses drivers such as geckodriver, and chromedriver to open (and close) browser instances and then hits those instances with actions.
Selenium Grid is a stand-alone server that will run your WebDriver tests remotely on a node and reports back. So if you wanted to use another machines resources to run your test-suite you would be able to do so. It also allows you to combine multiple machines resources by assigning each a node and Selenium Grid will distribute your tests evenly.
As far as your questions about multi-threading,
Is it recommended to use Grid over Selenium WebDriver in a multithreaded environment?
Grid is just a remote-runner of WebDriver. WebDriver is the test-framework. I assume your goal is to reduce your test-suite's run-time by running tests in parallel? Parallel testing can be done on your local machine using WebDriver or can be configured on a Selenium Grid. In my experience, I have gotten more lucky on my local machine than on Grid but both essentially face the same problem. The main danger for parallel testing using WebDriver is thread-safety. JUnit 4.7 onwards and Test-NG RELEASE allow for parallel testing. I highly suggest using Test-NG instead of JUnit for this purpose.
To prevent concurrency issues, your main goal will be to make all your shared resources isolated within each thread. A secondary goal is to limit the scope of all variables to its method. This can be done using a static instance of ThreadLocal It is also really useful to force the initializing of driver instances to be frozen in synchronized methods.
Creating Resources
public class DriverFactory {
private static String grid = "http://localhost:4444/wd/hub";
public static ThreadLocal<WebDriver> drivers = new ThreadLocal<WebDriver>();
public static synchronized void newDriver() {
ChromeOptions options = new ChromeOptions(); // Assuming Chrome use
options.addArguments("--start-maximized");
// USE THIS FOR LOCAL
// tlDriver.set(new ChromeDriver(options));
// USE THIS FOR GRID
try {
drivers.set(new RemoteWebDriver(new URL(grid),options));
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
public static synchronized WebDriver getDriver() {
return drivers.get();
}
}
Test Class
public class GoogleTest {
@BeforeMethod
public void setup() {
DriverFactory.newDriver();
}
@Test
public void test1() {
WebDriver driver = DriverFactory.getDriver();
driver.navigate().to("https:\\www.google.com");
Assert.assertEquals(driver.getTitle(), "Google");
}
@Test
public void test2() {
WebDriver driver = DriverFactory.getDriver();
driver.navigate().to("https:\\www.google.com");
Assert.assertEquals(driver.getTitle(), "Google");
}
@AfterMethod
public void tearDown() {
WebDriver driver = DriverFactory.getDriver();
driver.quit();
}
}
TestNG.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<!-- thread-count should be = to maxSessions on your Grid -->
<suite name="Whatever" parallel="methods" thread-count="5">
<test name="Sample">
<classes>
<class name="GoogleTest"/>
</classes>
</test>
</suite>
Source: Making your Tests Thread-Safe, Full Guide
Versions Used: TestNG 6.14.3, Selenium 3.11, Selenium Grid 3.14.3
Also, would Selenium Grid take responsibility of cleaning any stale browser instances in its nodes (out of the box)?
Selenium Grid has timeout and a browserTimeout features to free up nodes and close browser instances. Although in my experience I would implore you to control any expected timeouts in your test-cases and have WebDriver close the browser instance, not Selenium Grid. You really want to prevent this from happening and eliminate all causes of un-expected hanging. Test-suites are designed to be quick feedback and are only useful if failures are indicative of an actual failure, not just a dirty test-suite. Also stale nodes/browsers can force you to have to constantly reset your grid + nodes which is a major detriment.