diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4e6bb2b7a5dbdaf036049de2aedf0baa572fc126..ee83991608f2cd6db86d907d1ac5c8e53013e4ea 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,3 +4,4 @@ have been made so far, between releases.
 
 # v1.3.1
 
+* coolamqp.objects.Callable made threadsafe (fixes #22)
\ No newline at end of file
diff --git a/coolamqp/__init__.py b/coolamqp/__init__.py
index a1d2230652252c6a5d5f6a31b3da8a229d0c0c0f..d98f7f7b0d1406629550e5690332ea91482f339b 100644
--- a/coolamqp/__init__.py
+++ b/coolamqp/__init__.py
@@ -1 +1 @@
-__version__ = '1.3.1a1'
+__version__ = '1.3.1a2'
diff --git a/coolamqp/objects.py b/coolamqp/objects.py
index 65d9db0bc849e69d12fcd7cd89356db5a4131e15..b396d35dd6c79ca7b9349ab189ef5c59debc81df 100644
--- a/coolamqp/objects.py
+++ b/coolamqp/objects.py
@@ -3,6 +3,7 @@
 Core objects used in CoolAMQP
 """
 import logging
+import threading
 import typing as tp
 import uuid
 
@@ -33,23 +34,24 @@ class Callable(object):
     """
     Add a bunch of callables to one list, and just invoke'm.
     INTERNAL USE ONLY
-    #todo not thread safe
     """
-    __slots__ = ('callables', 'oneshots')
+    __slots__ = ('callables', 'oneshots', 'lock')
 
     def __init__(self, oneshots=False):
         """:param oneshots: if True, callables will be called and discarded"""
         self.callables = []
+        self.lock = threading.Lock()
         self.oneshots = oneshots
 
-    def add(self, callable):
-        self.callables.append(callable)
+    def add(self, clbl):
+        self.callables.append(clbl)
 
     def __call__(self, *args, **kwargs):
-        for callable in self.callables:
-            callable(*args, **kwargs)
-        if self.oneshots:
-            self.callables = []
+        with self.lock:
+            for clbl in self.callables:
+                clbl(*args, **kwargs)
+            if self.oneshots:
+                self.callables = []
 
 
 class Message(object):