Transactional memory ensures the atomicity and isolation of transactions. Although these properties greatly simplify reasoning about concurrent programs, they prevent concurrent transactions from interacting with each other. In this paper, we propose a synchronizer mechanism for augmenting software transactional memory implementations to allow different transactions to communicate with each other by accessing shared data. A synchronizer encapsulates shared data, which can be accessed only by those threads that synchronize at the synchronizer. All threads synchronized at a synchronizer can see the effects on that data by any concurrent threads (which must also be synchronized on that synchronizer). Such interaction necessarily compromises isolation. We limit the extent of this compromise by forcing all the threads synchronized on a synchronizer to commit or abort together. We describe how to implement synchronizers in the context of Dynamic Software Transactional Memory of Herlihy, Luchangco, Moir and Scherer.