多说一句 为什么没有新建一个Runnable对象 ? 因为我们不是研究同一个对象的数据被多个线程共享的问题。
我们只是为了研究作为一个同步方法被多个线程竞争调用的同时,这个类里面别的同步方法是阻塞还是运行状态,所以只是新建了一个ThisLock 对象。
@Test
public void test() throws InterruptedException {
//那个被多个线程来共同操作的对象
ThisLock thisLock = new ThisLock();
//线程 t1
Thread t1 = new Thread("t1"){
@Override
public void run() {
try {
thisLock.m1();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
//线程 t2
Thread t2 = new Thread("t2"){
@Override
public void run() {
try {
thisLock.m2();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
//--------------------------------------------------
t1.start();
t2.start();
//加入join是因为junit在执行完测试方法 就关闭jvm了 所以其他线程还没运行完就意外退出了。。。。
t1.join();
t2.join();
}
public static void print(Object o){
System.out.println(o);
}
public class ThisLock {
//方法m1
public synchronized void m1() throws InterruptedException {
int i= 0;
while (true){
Thread.sleep(1_000);
print(Thread.currentThread().getName()+"------m1------value"+String.valueOf(i++));
if(i==5){
break;
}
}
}
//方法m2
public synchronized void m2() throws InterruptedException {
int i= 0;
while (true){
Thread.sleep(1_000);
print(Thread.currentThread().getName()+"------m2------value"+String.valueOf(i++));
if(i==5){
break;
}
}
}
private void print(Object o){
System.out.println(o);
}
}
执行test方法 可以看到如下运行结果 :
t1------m1------value0
t1------m1------value1
t1------m1------value2
t1------m1------value3
t1------m1------value4
t2------m2------value0
t2------m2------value1
t2------m2------value2
t2------m2------value3
t2------m2------value4
t1抢到了cpu执行权 m1方法是一个死循环 所以一直执行m1 方法 t2线程一直处于block状态
等m1方法执行结束后 释放了this锁 m2方法才能执行
注意下面的代码: 如果把m2方法的 synchronized 关键字去掉呢 ????
public class ThisLock {
//方法m1
public synchronized void m1() throws InterruptedException {
int i= 0;
while (true){
Thread.sleep(1_000);
print(Thread.currentThread().getName()+"------m1------value"+String.valueOf(i++));
if(i==5){
break;
}
}
}
//方法m2
public void m2() throws InterruptedException {
int i= 0;
while (true){
Thread.sleep(1_000);
print(Thread.currentThread().getName()+"------m2------value"+String.valueOf(i++));
if(i==5){
break;
}
}
}
private void print(Object o){
System.out.println(o);
}
}
程序执行的流程如下:
t2------m2------value0
t1------m1------value0
t2------m2------value1
t1------m1------value1
t2------m2------value2
t1------m1------value2
t2------m2------value3
t1------m1------value3
t1------m1------value4
t2------m2------value4
可以看出 t1 t2 线程 m1 m2 方法都在各自的运行 (因为m2方法是普通方法了 没有锁 自然也就没有限制了)
当然 你也可以在m2方法里 放一个同步代码块 但是锁对象随便定义一个 (比如 new Object()) 由于 object 和 thislock 是两个对象 也就是两把锁 多线程操作这两个方法 也是互不影响的