并发

synchronzied偏向锁与linux源码调用关系

2019-12-01  本文已影响0人  loveFXX

示例代码

public class SyncDemo {

    static {
        System.loadLibrary( "MyThreadSyncNative" );
    }
    Object o= new Object();
    public static void main(String[] args) throws InterruptedException {
        System.out.println("-------------------------");
        Thread.sleep(5000);
        SyncDemo syncDemo = new SyncDemo();
        syncDemo.start();
    }
    public void start() {
        Thread thread = new Thread() {
            public void run() {
                while (true) {
                    try {
                        Thread.sleep(500);
                        sync();
                    } catch (InterruptedException e) {

                    }
                }
            }
        };

        Thread thread2 = new Thread() {
            @Override
            public void run() {
                while (true) {
                    try {
                        Thread.sleep(500);
                        sync();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };

        thread.setName("t1");
//      thread2.setName("t2");
        thread.start();
//      thread2.start();
    }


    public native void  getMytid();
    public  void sync() throws InterruptedException {
        synchronized (o) {
            getMytid();//打印了当前线程的id
        }
    }
}

对于示例代码分析,使用synchronized关键字。如果thread2线程不执行,持有锁将会是偏向锁。thread2运行将会变成重量级锁。

synchronized

synchronized种类:
1、偏向锁 (方法需要保持线程安全,实际情况不一定有互斥,所以偏向锁是synchronzied锁的对象如果没有资源竞争的情况下存在的。 只会调用一次os函数实现)
2、轻量级锁
3、重量级锁(互斥 借助os函数来实现的锁)
java锁的实现对应操作系统函数(在pthread_mutex_lock.c文件)
java锁有关的操作系统相关方法
pthread_mutex_t pthread_mutex_init pthread_mutex_lock pthread_mutex_unlock

linux编译glibc

下面编译glibc是在18.04.1-Ubuntu环境


image.png
下载glibc

http://ftp.gnu.org/gnu/glibc/
首先,查看当前版本(2.27)
ldd --version

安装jdk

apt-get install openjdk-8-jdk

安装gcc make gawk bison

apt-get install gcc -y
apt-get install make gawk bison -y

下载glibc

与之前版本相同的
wget http://ftp.gnu.org/gnu/glibc/glibc-2.27.tar.gz

解压

tar zxvf glibc-2.27.tar.gz
cd glibc-2.27

修改pthread_mutex_lock.c

/root/glibc-2.27/nptl/pthread_mutex_lock.c文件
添加 #include <stdio.h>
fprintf(stderr,"my message tid=%lu\n",pthread_self());


image.png
新建目录

cd /root/glibc-2.27/
mkdir myglib
cd myglib/

编译

../configure --prefix=/usr
(或编译命令../configure --prefix=/usr --disable-profile --enable-add-ons --with-head=/usr/include --with-binutils=/usr/bin)
make
make install

生成so文件

示例代码调用了本地方法getMytid,System.loadLibrary( "MyThreadSyncNative" );调用加载系统库。具体步骤可参考【java线程模型】
由于,我修改了pthread_mutex_lock.c文件。运行java命令


image.png

到这里说明glibc编译成功

证明偏向锁

证明synchronzied偏向锁只会调用一次操作系统函数
根据示例代码测试


image.png

把示例代码中thread2.start();注释去掉,即两个线程运行


image.png

总结:

java对象持有锁与操作系统锁一一对应关系
jvm不推荐(stop()方法)停止一个线程,一定要执行完 。使用interrupt方法
interrupt方法
1、优雅停止线程,资源能够释放。
2、能解阻塞,继续往下执行。
3、可以给isInterrupted赋值

上一篇下一篇

猜你喜欢

热点阅读