补充知识:
操作锁的原理有两种方式:
- 通过在内存上阻止多线程对对象的获取
- 在指令集上阻止多线程对指令的执行
Java中的每个对象都有一个monitor对象,加锁就是在竞争monitor对象,对代码块加锁是通过在指令前后添加monitorenter和monitorexit 指令实现的。
Synchronized 主要通过操作对象的monitor对象来实现锁的
- synchronized 作用于成员变量和非静态方法时,锁住的是对象实例
- synchronized 作用于静态方法时,锁住的是对应类,的Class实例对象
- synchronized 作用于一个代码块时,锁住的是所有代码块中配置的对象
// 作用于成员变量和非静态方法
一个对象
public class TestThread {
public synchronized void thread1() throws InterruptedException {
for(int i =0;i<10;i++){
Thread.sleep(10);
System.out.println("线程1");
}
}
public synchronized void thread2() throws InterruptedException {
for(int i =0;i<10;i++){
Thread.sleep(10);
System.out.println("线程2");
}
}
public static void main(String[] args) {
TestThread tt = new TestThread();
ExecutorService es = Executors.newFixedThreadPool(5);
es.execute(new Runnable() {
@SneakyThrows
@Override
public void run() {
tt.thread1();
}
});
es.execute(new Runnable() {
@SneakyThrows
@Override
public void run() {
tt.thread2();
}
});
es.shutdown();
}
}
两个对象
public class TestThread {
public synchronized void thread1() throws InterruptedException {
for(int i =0;i<10;i++){
Thread.sleep(10);
System.out.println("线程1");
}
}
public synchronized void thread2() throws InterruptedException {
for(int i =0;i<10;i++){
Thread.sleep(10);
System.out.println("线程2");
}
}
public static void main(String[] args) {
TestThread tt = new TestThread();
TestThread tt2 = new TestThread();
ExecutorService es = Executors.newFixedThreadPool(5);
es.execute(new Runnable() {
@SneakyThrows
@Override
public void run() {
tt.thread1();
}
});
es.execute(new Runnable() {
@SneakyThrows
@Override
public void run() {
tt2.thread2();
}
});
es.shutdown();
}
}
// 作用于静态变量
public class TestThread {
public static synchronized void thread1() throws InterruptedException {
for(int i =0;i<10;i++){
Thread.sleep(10);
System.out.println("线程1");
}
}
public static synchronized void thread2() throws InterruptedException {
for(int i =0;i<10;i++){
Thread.sleep(10);
System.out.println("线程2");
}
}
public static void main(String[] args) {
TestThread tt = new TestThread();
TestThread tt2 = new TestThread();
ExecutorService es = Executors.newFixedThreadPool(5);
es.execute(new Runnable() {
@SneakyThrows
@Override
public void run() {
thread1();
}
});
es.execute(new Runnable() {
@SneakyThrows
@Override
public void run() {
thread2();
}
});
es.shutdown();
}
}
作用于代码块
public class TestThread {
private static String a = "aa";
public void thread1() throws InterruptedException {
synchronized (a){
for(int i =0;i<10;i++){
Thread.sleep(10);
System.out.println("线程1");
}
}
}
public synchronized void thread2() throws InterruptedException {
synchronized (a){
for(int i =0;i<10;i++){
Thread.sleep(10);
System.out.println("线程2");
}
}
}
public static void main(String[] args) {
TestThread tt = new TestThread();
TestThread tt2 = new TestThread();
ExecutorService es = Executors.newFixedThreadPool(5);
es.execute(new Runnable() {
@SneakyThrows
@Override
public void run() {
tt.thread1();
}
});
es.execute(new Runnable() {
@SneakyThrows
@Override
public void run() {
tt2.thread2();
}
});
es.shutdown();
}
}