synchronized修饰静态/非静态方法
public static void main(String[] args) {
Thread t1 = new Thread() {
@Override
public void run() {
Person.m1("线程1");
}
};
Thread t2 = new Thread() {
@Override
public void run() {
Person.m1("线程2");
}
};
t1.start();
t2.start();
}
public class Person {
public synchronized static void m1(String x) {
System.out.println(x + "ing");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(x + "执行");
}
}
在有synchronized修饰静态方法时,线程1和线程2有一个会先执行,此时就会锁住,知道执行结束才会释放锁,另一个线程才会执行。
synchronized修饰静态方法可以叫类锁,当执行一个带锁的方法,其他静态带锁的方法就不能执行了(静态的存在方法区)。
synchronized修饰非静态方法和修饰静态方法一样,只不过是在堆中,一个对象调用synchronized修饰的非静态方法时,其他非静态带锁的也不能执行了。
加锁的和不加锁的互不影响,不是同一个对象的锁互不影响,不是同一类的锁也互不影响。
读要在写之后
public static void main(String[] args) {
Person p = new Person();
Person p2 = new Person();
Thread t1 = new Thread() {
@Override
public void run() {
for (int i = 0; i < 100000; i++) {
p.m1(1);
}
}
};
Thread t2 = new Thread() {
@Override
public void run() {
for (int i = 0; i < 100000; i++) {
p.m1(1);
}
}
};
Thread t3 = new Thread() {
@Override
public void run() {
for (int i = 0; i < 100000; i++) {
int x = p2.getMoney2() + 1;
p2.setMoney(x);
}
}
};
Thread t4 = new Thread() {
@Override
public void run() {
for (int i = 0; i < 100000; i++) {
int x = p2.getMoney2() + 1;
p2.setMoney(x);
}
}
};
t1.start(); //在这个线程执行完,才会执行后面的线程,不用这个的话主线程大概会先执行完
t2.start();
t3.start();
t4.start();
try {
t1.join();
t2.join();
t3.join();
t4.join();
} catch (
InterruptedException e) {
e.printStackTrace();
}
System.out.println(p.getMoney1());
System.out.println(p2.getMoney2());
}
public class Person {
public static int money = 0;
public static int money2 = 0;
//进行完写操作才释放锁
public synchronized static void m1(int x) {
money += x;
}
//读方法
public synchronized int getMoney1() {
return money;
}
//读方法
public synchronized int getMoney2() {
return money2;
}
//写方法
public synchronized static void setMoney(int x) {
money2 = x;
}
}
输出结果:
由这个结果可知,读要在写之后,在读和写分开的情况下,可能只在读完方法就出栈了释放了锁,都没有进行写操作,其他的还是读到写之前的值。在都没有进行写操作的情况下,都读到了初值。
?
|