#include <mutex>
#include <thread>
#include <iostream>

struct Point
{
public:
  void getXY(double& x, double& y) const;
  void setXY(double x, double y);
private:
  double xcoord;
  double ycoord;
  mutable std::mutex m;
};


void Point::getXY(double& x, double& y) const
{
  std::lock_guard<std::mutex> lg(m);
  x = xcoord;
  y = ycoord;
}

void Point::setXY(double x, double y)
{
  std::lock_guard<std::mutex> lg(m);
  xcoord = x;
  ycoord = y;
}

void printPoint(const Point &p)
{
  double x, y;
  p.getXY(x, y);
  std::cout << "X: " << x 
            << ", Y: " << y << std::endl;
}

void increasePoint(Point &p)
{
  double x, y;
  p.getXY(x, y);
  p.setXY(x * 2, y * 2);
}

int main()
{
  Point p;
  p.setXY(1.1, -1.1);

  std::thread t1(printPoint, std::ref(p));
  std::thread t2(increasePoint, std::ref(p));
  std::thread t3(increasePoint, std::ref(p));
  std::thread t4(printPoint, std::ref(p));
 
  t1.join(); t2.join(); t3.join(); t4.join();
  return 0;
}