diff --git a/core/src/main/java/haveno/core/trade/protocol/BuyerProtocol.java b/core/src/main/java/haveno/core/trade/protocol/BuyerProtocol.java
index 84d850c7..0eb410ce 100644
--- a/core/src/main/java/haveno/core/trade/protocol/BuyerProtocol.java
+++ b/core/src/main/java/haveno/core/trade/protocol/BuyerProtocol.java
@@ -55,27 +55,30 @@ public class BuyerProtocol extends DisputeProtocol {
         super.onInitialized();
 
         // re-send payment sent message if not acked
-        synchronized (trade) {
-            if (trade.isShutDownStarted()) return;
-            if (trade.getState().ordinal() >= Trade.State.BUYER_SENT_PAYMENT_SENT_MSG.ordinal() && trade.getState().ordinal() < Trade.State.SELLER_RECEIVED_PAYMENT_SENT_MSG.ordinal()) {
-                latchTrade();
-                given(anyPhase(Trade.Phase.PAYMENT_SENT)
-                    .with(BuyerEvent.STARTUP))
-                    .setup(tasks(
-                            BuyerSendPaymentSentMessageToSeller.class,
-                            BuyerSendPaymentSentMessageToArbitrator.class)
-                    .using(new TradeTaskRunner(trade,
-                            () -> {
-                                unlatchTrade();
-                            },
-                            (errorMessage) -> {
-                                log.warn("Error sending PaymentSentMessage on startup: " + errorMessage);
-                                unlatchTrade();
-                            })))
-                    .executeTasks();
-                awaitTradeLatch();
+        ThreadUtils.execute(() -> {
+            if (trade.isShutDownStarted() || trade.isPayoutPublished()) return;
+            synchronized (trade) {
+                if (trade.isShutDownStarted() || trade.isPayoutPublished()) return;
+                if (trade.getState().ordinal() >= Trade.State.BUYER_SENT_PAYMENT_SENT_MSG.ordinal() && trade.getState().ordinal() < Trade.State.SELLER_RECEIVED_PAYMENT_SENT_MSG.ordinal()) {
+                    latchTrade();
+                    given(anyPhase(Trade.Phase.PAYMENT_SENT)
+                        .with(BuyerEvent.STARTUP))
+                        .setup(tasks(
+                                BuyerSendPaymentSentMessageToSeller.class,
+                                BuyerSendPaymentSentMessageToArbitrator.class)
+                        .using(new TradeTaskRunner(trade,
+                                () -> {
+                                    unlatchTrade();
+                                },
+                                (errorMessage) -> {
+                                    log.warn("Error sending PaymentSentMessage on startup: " + errorMessage);
+                                    unlatchTrade();
+                                })))
+                        .executeTasks();
+                    awaitTradeLatch();
+                }
             }
-        }
+        }, trade.getId());
     }
 
     @Override
diff --git a/core/src/main/java/haveno/core/trade/protocol/SellerProtocol.java b/core/src/main/java/haveno/core/trade/protocol/SellerProtocol.java
index 7408fc25..2559a55d 100644
--- a/core/src/main/java/haveno/core/trade/protocol/SellerProtocol.java
+++ b/core/src/main/java/haveno/core/trade/protocol/SellerProtocol.java
@@ -51,27 +51,30 @@ public class SellerProtocol extends DisputeProtocol {
         super.onInitialized();
 
         // re-send payment received message if payout not published
-        synchronized (trade) {
-            if (trade.isShutDownStarted()) return;
-            if (trade.getState().ordinal() >= Trade.State.SELLER_SENT_PAYMENT_RECEIVED_MSG.ordinal() && !trade.isPayoutPublished()) {
-                latchTrade();
-                given(anyPhase(Trade.Phase.PAYMENT_RECEIVED)
-                    .with(SellerEvent.STARTUP))
-                    .setup(tasks(
-                            SellerSendPaymentReceivedMessageToBuyer.class,
-                            SellerSendPaymentReceivedMessageToArbitrator.class)
-                    .using(new TradeTaskRunner(trade,
-                            () -> {
-                                unlatchTrade();
-                            },
-                            (errorMessage) -> {
-                                log.warn("Error sending PaymentReceivedMessage on startup: " + errorMessage);
-                                unlatchTrade();
-                            })))
-                    .executeTasks();
-                awaitTradeLatch();
+        ThreadUtils.execute(() -> {
+            if (trade.isShutDownStarted() || trade.isPayoutPublished()) return;
+            synchronized (trade) {
+                if (trade.isShutDownStarted() || trade.isPayoutPublished()) return;
+                if (trade.getState().ordinal() >= Trade.State.SELLER_SENT_PAYMENT_RECEIVED_MSG.ordinal() && !trade.isPayoutPublished()) {
+                    latchTrade();
+                    given(anyPhase(Trade.Phase.PAYMENT_RECEIVED)
+                        .with(SellerEvent.STARTUP))
+                        .setup(tasks(
+                                SellerSendPaymentReceivedMessageToBuyer.class,
+                                SellerSendPaymentReceivedMessageToArbitrator.class)
+                        .using(new TradeTaskRunner(trade,
+                                () -> {
+                                    unlatchTrade();
+                                },
+                                (errorMessage) -> {
+                                    log.warn("Error sending PaymentReceivedMessage on startup: " + errorMessage);
+                                    unlatchTrade();
+                                })))
+                        .executeTasks();
+                    awaitTradeLatch();
+                }
             }
-        }
+        }, trade.getId());
     }
 
     @Override