- synchronized:关键字synchronized取得的锁都是对象锁,而不是把一段代码(方法)当做锁,所以代码中哪个线程先执行synchronized关键字的方法,哪个线程就持有该方法所属对象的锁(Lock)
- public class MultiThread {
- private int num = 0;
- /** static */
- public synchronized void printNum(String tag){
- try {
- if(tag.equals("a")){
- num = 100;
- System.out.println("tag a, set num over!");
- Thread.sleep(1000);
- } else {
- num = 200;
- System.out.println("tag b, set num over!");
- }
- System.out.println("tag " + tag + ", num = " + num);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- //注意观察run方法输出顺序
- public static void main(String[] args) {
- //俩个不同的对象
- final MultiThread m1 = new MultiThread();
- final MultiThread m2 = new MultiThread();
- Thread t1 = new Thread(new Runnable() {
- @Override
- public void run() {
- m1.printNum("a");
- }
- });
- Thread t2 = new Thread(new Runnable() {
- @Override
- public void run() {
- m2.printNum("b");
- }
- });
- t1.start();
- t2.start();
- }
- }
- 输出结果:
- tag b, set num over!
- tag a, set num over!
- tag b, num = 200
- tag a, num = 100
- 在静态方法上加synchronized关键字,表示锁定.class类,类一级别的锁(独占.class类)。
- public class MultiThread {
- private static int num = 0;
- /** static */
- 在方法上加了static
- public static synchronized void printNum(String tag){
- try {
- if(tag.equals("a")){
- num = 100;
- System.out.println("tag a, set num over!");
- Thread.sleep(1000);
- } else {
- num = 200;
- System.out.println("tag b, set num over!");
- }
- System.out.println("tag " + tag + ", num = " + num);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- //注意观察run方法输出顺序
- public static void main(String[] args) {
- //俩个不同的对象
- final MultiThread m1 = new MultiThread();
- final MultiThread m2 = new MultiThread();
- Thread t1 = new Thread(new Runnable() {
- @Override
- public void run() {
- m1.printNum("a");
- }
- });
- Thread t2 = new Thread(new Runnable() {
- @Override
- public void run() {
- m2.printNum("b");
- }
- });
- t1.start();
- t2.start();
- }
- }
- 输出结果:
- tag a, set num over!
- tag a, num = 100
- tag b, set num over!
- tag b, num = 200
- 关键字synchronized拥有锁重入的功能,在使用synchronized时,当一个线程的到一个对象锁以后,再次请求此对象是可以再次得到该对象的锁。
- public class SyncDubbo1 {
- public synchronized void method1(){
- System.out.println("method1..");
- method2();
- }
- public synchronized void method2(){
- System.out.println("method2..");
- method3();
- }
- public synchronized void method3(){
- System.out.println("method3..");
- }
- public static void main(String[] args) {
- final SyncDubbo1 sd = new SyncDubbo1();
- Thread t1 = new Thread(new Runnable() {
- @Override
- public void run() {
- sd.method1();
- }
- });
- t1.start();
- }
- }
- 输出结果:
- method1..
- method2..
- method3..
- public class SyncDubbo2 {
- static class Main {
- public int i = 10;
- public synchronized void operationSup(){
- try {
- i--;
- System.out.println("Main print i = " + i);
- Thread.sleep(100);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- static class Sub extends Main {
- public synchronized void operationSub(){
- try {
- while(i > 0) {
- i--;
- System.out.println("Sub print i = " + i);
- Thread.sleep(100);
- this.operationSup();
- }
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- public static void main(String[] args) {
- Thread t1 = new Thread(new Runnable() {
- @Override
- public void run() {
- Sub sub = new Sub();
- sub.operationSub();
- }
- });
- t1.start();
- }
- }
- 输出结果:
- Sub print i = 9
- Main print i = 8
- Sub print i = 7
- Main print i = 6
- Sub print i = 5
- Main print i = 4
- Sub print i = 3
- Main print i = 2
- Sub print i = 1
- Main print i = 0
- 出现异常,锁会自动释放
- public class SyncException {
- private int i = 0;
- public synchronized void operation(){
- while(true){
- try {
- i++;
- Thread.sleep(100);
- System.out.println(Thread.currentThread().getName() + " , i = " + i);
- if(i == 8){
- 异常释放锁
- throw new RuntimeException();
- }
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- public static void main(String[] args) {
- final SyncException se = new SyncException();
- Thread t1 = new Thread(new Runnable() {
- @Override
- public void run() {
- se.operation();
- }
- },"t1");
- t1.start();
- }
- }
- 输出结果:
- t1 , i = 1
- t1 , i = 2
- t1 , i = 3
- t1 , i = 4
- t1 , i = 5
- t1 , i = 6
- t1 , i = 7
- t1 , i = 8
- Exception in thread "t1" java.lang.RuntimeException
- at com.bjsxt.base.sync005.SyncException.operation(SyncException.java:18)
- at com.bjsxt.base.sync005.SyncException$1.run(SyncException.java:32)
- at java.lang.Thread.run(Thread.java:745)
- 对于web应用程序,异常释放锁,如果不及时处理,很可能对应用程序业务逻辑产生严重的错误,比如现在执行一个队列任务,很多对象都在等待第一个对象正确执行完毕后再去释放锁,但是由于第一个对象出现异常导致业务逻辑没有正常执行完毕,就释放了锁,那么可想而知后续对象执行的都是错误的。所以这一点一定要注意。
2.synchronized
最新推荐文章于 2022-10-07 00:15:41 发布
