I have two use cases.
A. I want to synchronise access to a queue for two threads.
B. I want to synchronise access to a queue for two threads and use a conditio
They are not really same mutexes, lock_guard<muType> has nearly the same as std::mutex, with a difference that it's lifetime ends at the end of the scope (D-tor called) so a clear definition about these two mutexes  :
lock_guard<muType> has a mechanism for owning a mutex for the duration of a scoped block.
And
unique_lock<muType> is a wrapper allowing deferred locking, time-constrained attempts at locking, recursive locking, transfer of lock ownership, and use with condition variables.
Here is an example implemetation :
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <functional>
#include <chrono>
using namespace std::chrono;
class Product{
   public:
       Product(int data):mdata(data){
       }
       virtual~Product(){
       }
       bool isReady(){
       return flag;
       }
       void showData(){
        std::cout<<mdata<<std::endl;
       }
       void read(){
         std::this_thread::sleep_for(milliseconds(2000));
         std::lock_guard<std::mutex> guard(mmutex);
         flag = true;
         std::cout<<"Data is ready"<<std::endl;
         cvar.notify_one();
       }
       void task(){
       std::unique_lock<std::mutex> lock(mmutex);
       cvar.wait(lock, [&, this]() mutable throw() -> bool{ return this->isReady(); });
       mdata+=1;
       }
   protected:
    std::condition_variable cvar;
    std::mutex mmutex;
    int mdata;
    bool flag = false;
};
int main(){
     int a = 0;
     Product product(a);
     std::thread reading(product.read, &product);
     std::thread setting(product.task, &product);
     reading.join();
     setting.join();
     product.showData();
    return 0;
}
In this example, i used the unique_lock<muType> with condition variable