今天我们来讨论一下,同一个类中的多个方法都加了同步锁,多个线程能同时访问同一个类中的这两 个方法吗?
- 第一种情况:使用synchronized关键字
/** * @program: * 使用 synchronized 时,当我们访问同一个类对象的时候,是同一把锁,所以可以访问 该对象的其他 synchronized 方法 * @description: ${description} * @author: Will Wu * @create: 2018-12-09 10:09 **/ @Slf4j public class MultiThreadO { private int count=0; private Lock lock=new ReentrantLock(); public Runnable runnableone=new Runnable() { @Override public void run() { //设置关键字synchronized,以当前类为锁 synchronized (this){ while (count<100){ log.info(Thread.currentThread().getName()+"run 1:"+count++); } } } }; public Runnable runnabletwo=new Runnable() { @Override public void run() { synchronized (this){ while (count<100){ log.info(Thread.currentThread().getName()+"run 2:"+count++); } } } }; public static void main(String[] args) { MultiThreadO multiThread = new MultiThreadO(); new Thread(multiThread.runnableone).start(); new Thread(multiThread.runnabletwo).start(); } }
运行结果如下:
-
/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/bin/java -Dfile.encoding=UTF-8 -classpath /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/deploy.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/ext/cldrdata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/ext/dnsns.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/ext/jaccess.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/ext/jfxrt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/ext/localedata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/ext/nashorn.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/ext/sunec.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/ext/zipfs.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/javaws.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/jfxswt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/management-agent.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/plugin.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/lib/ant-javafx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/lib/dt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/lib/javafx-mx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/lib/jconsole.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/lib/packager.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/lib/sa-jdi.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/lib/tools.jar:/Users/wuyundong/IdeaProjects/demo/target/classes:/Users/wuyundong/.m2/repository/org/springframework/boot/spring-boot-starter/2.1.1.RELEASE/spring-boot-starter-2.1.1.RELEASE.jar:/Users/wuyundong/.m2/repository/org/springframework/boot/spring-boot/2.1.1.RELEASE/spring-boot-2.1.1.RELEASE.jar:/Users/wuyundong/.m2/repository/org/springframework/spring-context/5.1.3.RELEASE/spring-context-5.1.3.RELEASE.jar:/Users/wuyundong/.m2/repository/org/springframework/spring-aop/5.1.3.RELEASE/spring-aop-5.1.3.RELEASE.jar:/Users/wuyundong/.m2/repository/org/springframework/spring-beans/5.1.3.RELEASE/spring-beans-5.1.3.RELEASE.jar:/Users/wuyundong/.m2/repository/org/springframework/spring-expression/5.1.3.RELEASE/spring-expression-5.1.3.RELEASE.jar:/Users/wuyundong/.m2/repository/org/springframework/boot/spring-boot-autoconfigure/2.1.1.RELEASE/spring-boot-autoconfigure-2.1.1.RELEASE.jar:/Users/wuyundong/.m2/repository/org/springframework/boot/spring-boot-starter-logging/2.1.1.RELEASE/spring-boot-starter-logging-2.1.1.RELEASE.jar:/Users/wuyundong/.m2/repository/ch/qos/logback/logback-classic/1.2.3/logback-classic-1.2.3.jar:/Users/wuyundong/.m2/repository/ch/qos/logback/logback-core/1.2.3/logback-core-1.2.3.jar:/Users/wuyundong/.m2/repository/org/apache/logging/log4j/log4j-to-slf4j/2.11.1/log4j-to-slf4j-2.11.1.jar:/Users/wuyundong/.m2/repository/org/apache/logging/log4j/log4j-api/2.11.1/log4j-api-2.11.1.jar:/Users/wuyundong/.m2/repository/org/slf4j/jul-to-slf4j/1.7.25/jul-to-slf4j-1.7.25.jar:/Users/wuyundong/.m2/repository/javax/annotation/javax.annotation-api/1.3.2/javax.annotation-api-1.3.2.jar:/Users/wuyundong/.m2/repository/org/springframework/spring-core/5.1.3.RELEASE/spring-core-5.1.3.RELEASE.jar:/Users/wuyundong/.m2/repository/org/springframework/spring-jcl/5.1.3.RELEASE/spring-jcl-5.1.3.RELEASE.jar:/Users/wuyundong/.m2/repository/org/yaml/snakeyaml/1.23/snakeyaml-1.23.jar:/Users/wuyundong/.m2/repository/org/projectlombok/lombok/1.18.4/lombok-1.18.4.jar:/Users/wuyundong/.m2/repository/org/slf4j/slf4j-api/1.7.25/slf4j-api-1.7.25.jar com.example.demo.thread.MultiThreadO 10:22:04.589 [Thread-0] INFO com.example.demo.thread.MultiThreadO - Thread-0run 1:0 10:22:04.589 [Thread-1] INFO com.example.demo.thread.MultiThreadO - Thread-1run 2:1 10:22:04.595 [Thread-0] INFO com.example.demo.thread.MultiThreadO - Thread-0run 1:2 10:22:04.595 [Thread-1] INFO com.example.demo.thread.MultiThreadO - Thread-1run 2:3 10:22:04.595 [Thread-0] INFO com.example.demo.thread.MultiThreadO - Thread-0run 1:4 10:22:04.595 [Thread-1] INFO com.example.demo.thread.MultiThreadO - Thread-1run 2:5 10:22:04.595 [Thread-0] INFO com.example.demo.thread.MultiThreadO - Thread-0run 1:6 10:22:04.595 [Thread-1] INFO com.example.demo.thread.MultiThreadO - Thread-1run 2:7 10:22:04.595 [Thread-0] INFO com.example.demo.thread.MultiThreadO - Thread-0run 1:8 10:22:04.595 [Thread-1] INFO com.example.demo.thread.MultiThreadO - Thread-1run 2:9 10:22:04.595 [Thread-0] INFO com.example.demo.thread.MultiThreadO - Thread-0run 1:10 10:22:04.595 [Thread-1] INFO com.example.demo.thread.MultiThreadO - Thread-1run 2:11 10:22:04.595 [Thread-0] INFO com.example.demo.thread.MultiThreadO - Thread-0run 1:12 10:22:04.595 [Thread-1] INFO com.example.demo.thread.MultiThreadO - Thread-1run 2:13
从结果可以看到:
-
使用 synchronized 时,当我们访问同一个类对象的时候,是同一把锁,所以可以访问 该对象的其他 synchronized 方法
- 第二种情况:使用lock
/** * @program: 多个线程不可访问同一个类中的 2 个加了 Lock 锁的方法 * @description: ${description} * @author: Will Wu * @create: 2018-12-09 09:53 **/ @Slf4j public class MultiThread { private int count=0; //lock private Lock lock=new ReentrantLock(); private Runnable runnableone=new Runnable() { @Override public void run() { //lock lock.lock(); while (count<100){ try { //是否执行该方法 log.info(Thread.currentThread().getName()+"run 1:"+count++); } catch (Exception e) { e.printStackTrace(); } } lock.unlock(); } }; private Runnable runnabletwo=new Runnable() { @Override public void run() { lock.lock(); while(count<100){ log.info(Thread.currentThread().getName()+"run 2:"+count++); } lock.unlock(); } }; public static void main(String[] args) { MultiThread qq = new MultiThread(); new Thread(qq.runnableone).start(); new Thread(qq.runnabletwo).start(); } }
执行后结果如下:
-
10:27:11.310 [Thread-0] INFO com.example.demo.thread.MultiThread - Thread-0run 1:0 10:27:11.315 [Thread-0] INFO com.example.demo.thread.MultiThread - Thread-0run 1:1 10:27:11.315 [Thread-0] INFO com.example.demo.thread.MultiThread - Thread-0run 1:2 10:27:11.315 [Thread-0] INFO com.example.demo.thread.MultiThread - Thread-0run 1:3 10:27:11.315 [Thread-0] INFO com.example.demo.thread.MultiThread - Thread-0run 1:4 10:27:11.315 [Thread-0] INFO com.example.demo.thread.MultiThread - Thread-0run 1:5 10:27:11.315 [Thread-0] INFO com.example.demo.thread.MultiThread - Thread-0run 1:6 10:27:11.315 [Thread-0] INFO com.example.demo.thread.MultiThread - Thread-0run 1:7 10:27:11.315 [Thread-0] INFO com.example.demo.thread.MultiThread - Thread-0run 1:8 10:27:11.315 [Thread-0] INFO com.example.demo.thread.MultiThread - Thread-0run 1:9 10:27:11.315 [Thread-0] INFO com.example.demo.thread.MultiThread - Thread-0run 1:10 10:27:11.315 [Thread-0] INFO com.example.demo.thread.MultiThread - Thread-0run 1:11 10:27:11.315 [Thread-0] INFO com.example.demo.thread.MultiThread - Thread-0run 1:12 10:27:11.315 [Thread-0] INFO com.example.demo.thread.MultiThread - Thread-0run 1:13 10:27:11.315 [Thread-0] INFO com.example.demo.thread.MultiThread - Thread-0run 1:14 10:27:11.315 [Thread-0] INFO com.example.demo.thread.MultiThread - Thread-0run 1:15 10:27:11.315 [Thread-0] INFO com.example.demo.thread.MultiThread - Thread-0run 1:16 10:27:11.315 [Thread-0] INFO com.example.demo.thread.MultiThread - Thread-0run 1:17
因此:
-
多个线程不可访问同一个类中的 2 个加了 Lock 锁的方法;