我正在研究关键字synchronized
,但我不知道是否可以在同一类中插入2个同步语句;例如:
我使用这些简单的方法和两个锁定对象制作了一个类:
public class Locker1 {
private Object lock1= new Object();
private Object lock2= new Object();
public void printL1() {
synchronized(lock1) {
for(int i=0; i<50;i++) {
System.out.println(i);
}
}
}
public void printL2() {
synchronized(lock2) {
for(int i=0; i<50;i++) {
System.out.println("-"+i);
}
}
}
}
我制作了两个仅调用printL1
和printL2
的不同线程,据我所知,我认为由于这是两个不同的锁,我会看到交替打印正数和负数,因为可以并发,但是我尝试了多次,并且[ C0]总是完全发生在printL2
之后,不是一次我看到正数之间的负数,就是同步时丢失了什么吗?
这里是其余代码
printL1
public class ThreadA extends Thread {
private Locker1 l1;
public ThreadA(Locker1 l1) {
this.l1=l1;
}
public void run() {
l1.printL1();
}
}
和主要班级:
public class ThreadB extends Thread {
private Locker1 l1;
public ThreadB(Locker1 l1) {
this.l1=l1;
}
public void run() {
l1.printL2();
}
}
交错发生预期;仅进行了50次迭代就很难看到,因此多进行多次迭代就可以看到它
您对线程和锁的理解是正确的。由于public class Main {
public static void main(String[] args) {
Locker1 l1=new Locker1();
ThreadA tA=new ThreadA(l1);
ThreadB tB=new ThreadB(l1);
tA.start();
tB.start();
}
}
和Locker1.printL1()
将锁授予不同的对象,因此一个线程访问Locker1.printL2()
而另一个访问Locker1.printL1()
不应互相阻塞。
之所以在printL1之后看到完整的printL2结果,是因为该工作对CPU而言太少了。 50次迭代需要几分之一毫秒才能完成。在需要Locker1.printL2()
之前,任务已完成。
让任务休眠一小段时间,您就可以看到线程的产量。
context switch
输出:
public class Locker1 {
private Object lock1 = new Object();
private Object lock2 = new Object();
public void printL1() {
synchronized (lock1) {
for (int i = 0; i < 50; i++) {
System.out.println(i);
try {
Thread.sleep(50);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public void printL2() {
synchronized (lock2) {
for (int i = 0; i < 50; i++) {
System.out.println("-" + i);
try {
Thread.sleep(50);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}