学习笔记

    技术2023-11-08  101

    简述

    synchronized关键字可以使得被修饰的对象(此对象非实例化对象)在同一时间只能被同一个线程访问。 是一个非公平锁,即谁先抢到是谁的。

    结论

    修饰的对象争夺的对象非静态方法调用此方法的对象静态方法调用此方法的对象的类代码块后的括号内为类的class调用此代码块的对象的类代码块后的括号内为this调用此代码块的对象

    调试:

    一、修饰方法 我们启动两个线程去分别执行同一个类的两个对象中的f1方法,观察现象: 1、当synchronized修饰非静态方法时,控制台将每0.5秒输出两次线程名。 2、当synchronized修饰静态方法时,控制台将每0.5秒输出一次线程名。 也就是说

    修饰非静态方法:争夺的是调用此方法的对象。修饰静态方法:争夺的是调用此方法的对象的类(静态的属于类)。 class syn_Test { public synchronized static void f1() throws InterruptedException { System.out.println(Thread.currentThread().getName()); Thread.sleep(500); } } class ceshi { public static void main(String[] argv) throws Exception { syn_Test t1 = new syn_Test(); syn_Test t2 = new syn_Test(); new Thread(new Runnable() { @Override public void run() { try { while (true) { t1.f1(); } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }).start(); new Thread(new Runnable() { @Override public void run() { try { while (true) { t2.f1(); } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }).start(); } }

    二、修饰代码块 我们启动四个线程去分别执行同一个类的两个对象中的f1、f2方法,观察现象:

    很抱歉让您做了一次阅读理解

    1、当synchronized修饰的代码块内为this时,控制台将每0.5秒输出两次线程名。 2、当synchronized修饰的代码块内为类的class对象时控制台将每0.5秒输出一次线程名。 也就是说

    括号内为this时争夺的是调用此方法的对象括号内为类的class对象时争夺的是调用此方法的对象的类。 class syn_Test { public void f1() throws InterruptedException { synchronized (testTiaoJianSuo.class) { System.out.println(Thread.currentThread().getName()); Thread.sleep(500); } } public void f2() throws InterruptedException { synchronized (this) { System.out.println(Thread.currentThread().getName()); Thread.sleep(500); } } } class ceshi { public static void main(String[] argv) throws Exception { // 实例化两对象 syn_Test t1 = new syn_Test(); syn_Test t2 = new syn_Test(); // 启动四个进程分别执行两对象的四个方法 new Thread(new Runnable() { @Override public void run() { try { while (true) { t1.f1(); } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }).start(); new Thread(new Runnable() { @Override public void run() { try { while (true) { t1.f2(); } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }).start(); new Thread(new Runnable() { @Override public void run() { try { while (true) { t2.f1(); } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }).start(); new Thread(new Runnable() { @Override public void run() { try { while (true) { t2.f2(); } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }).start(); } }

    三、除此之外还有一个很有意思的问题:

    为什么在 static synchronized 修饰的方法中为什么不能调用notify()与notifyall()方法?

    我想够了挺久的,最后发现

    public final native void notify(); public final native void notifyAll();

    这俩没有用static修饰。

    Processed: 0.025, SQL: 9