Is it a good design for the implementation of the java sync keyword as an object?

Just for practice I wanted to implement the java synchronized keyword as a java object. Would you say the code below is a good design for this? I guess AtomicReference would have a similar performance to AtomicBoolean?

Updated code after suggestions:

public class SynchronizedBlock implements Runnable{

private final Lock lock;
private final Runnable runnable;

public SynchronizedBlock(Runnable r, Lock l){
    runnable = r;
    lock = l;
}

public void run() {
    try {
        while(!lock.compareAndSet(false, true)){
            Thread.sleep(100);
        }
        runnable.run();
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        lock.unlock();
    }

}

 }

 public class Lock {
private final AtomicReference<Boolean> locked = new AtomicReference<Boolean>(false);

public boolean compareAndSet(boolean expected, boolean update){
    return locked.compareAndSet(expected, update);
}

public boolean isLocked(){
    return locked.get();
}

public void unlock(){
    locked.set(false);
}
 }

@Test
public void test() {

    final SynchronizedBlock sb = new SynchronizedBlock(new Runnable(){

        public void run() {
            x++;
            System.out.println(x);
        }

    }, new Lock());

    Runnable r1 = new Runnable(){

        int c = 0;
        public void run() {
            while(c<10){
                sb.run();
                c++;
            }
        }

    };

    Runnable r2 = new Runnable(){

        int c = 0;
        public void run() {
            while(c<10){
                sb.run();
                c++;
            }
        }

    };

    Thread t1 = new Thread(r1);
    Thread t2 = new Thread(r2);

    t1.start();
    t2.start();

    while (t1.isAlive() && t2.isAlive()){

    }

    assertEquals(20,x);

}


You should add a method to encapsulate the compareAndSwap, and there is no point looping for the lock to be free before attempting to obtain it. Why get in the situation where you can see the lock is free but by the time you try to take it, it is gone.

I would remove the lock method and place the unlock in a finally lock so that an Exception/Error doesn't result in a lock which never unlocks.

Also I would use an AtomicBoolean which is more natural than an AtomicReference