Skip to content

Thread Safety

jdilallo edited this page Nov 25, 2013 · 5 revisions

##Threadsafety in the Java library

Classes defined in the new java library, like most classes in Java, are not threadsafe. Special care must be taken when using these objects in multiple threads. In general, we don’t recommend sharing instances of our classes in multiple threads. below is some code with comments explaining why.

// The credential object is threadsafe.
Credential credential = //...;

// The session object is not threadsafe.
AdWordsSession session = new AdWordsSession.Builder() // The Builders are not threadsafe.
    .fromFile()
    .withCredential(credential) // Uses thread-safe credential
    .build(); // /build() returns a brand new object every time.

// Threadsafe and lightweight.
AdWordsServices adWordsServices = new AdWordsServices(); 

// The Service “stubs” are NOT threadsafe.
// Stubs retain a reference to the session they are constructed for and will see any
// changes made to the session within the same thread.  When used in multiple threads it
// is possible to see the object in an inconsistent state, causing bugs.
MediaServiceInterface mediaService =
    adWordsServices.get(session, MediaServiceInterface.class);

Image image = new Image();
// Utilities such as Media are usually static and therefore threadsafe.
image.setData(Media.getMediaDataFromUrl("http://goo.gl/HJM3L"));
image.setType(MediaMediaType.IMAGE);

// ReportDownloader retains a reference to the session and is not threadsafe.
ReportDownloadResponse response =
    new ReportDownloader(session).downloadReport(reportDefinition);

##Service stubs Service stubs are the objects used to invoke webservice calls. CampaignService and CompanyService are two examples for AdWords and DFP respectively. These objects are not threadsafe and should have unique objects used per thread.

##Service locators Each product has a Services object such as AdWordsServices and DfpServices. These objects are threadsafe and can be re-used across threads. However, as mentioned above, the Service stubs returned by these classes are not.

Note that when you request a service stub from a service locator, you provide the session that will be used to make requests. If you make changes to the session, they will be used for all successive API calls.

#Sessions

AdWordsSession and DfpSession hold information such as credentials and options used when making requests. These objects are not threadsafe. It is possible to make writes to this object (.setClientCustomerId in AdWordsSession, for example) which might let other threads view this object in an inconsistent state.

###OAuth2 The Credential object is threadsafe. Therefore, you can reuse the same credential object for different sessions across multiple threads.

###AdWords Here’s a pattern than can be use to perform the same operation over multiple accounts:

AdWordsSession.Builder builder = new AdWordsSession.Builder()
    .withDeveloperToken(token)
    .withCredential(credential)
    .withUserAgent(userAgent);
for (String customerId: customerIds) {
  new FooThread(builder.withClientCustomerId(customerId).build()).start();
}

###DFP Here’s a pattern than can be use to perform different operations with the same account:

DfpSession.Builder builder = new DfpSession.Builder()
    .withNetworkCode(networkCode)
    .withCredential(credential)
    .withUserAgent(userAgent);

new FooThread(builder.build()).start();
new BarThread(builder.build()).start();
new BazThread(builder.build()).start();

##Utilities Most of the client library utility classes are static and therefore threadsafe. Classes such as the AdWords ReportDownloader are lightweight but not threadsafe (as it stores a reference to the session).

Clone this wiki locally