安裝CentOS-8.1.1911-x86_64-dvd1.iso(見VirtualBox安裝)
![]()
下載操作內核glibc庫
![]()
下載jdk上傳到linux
![]()
配置環境變數
export JAVA_HOME=/usr/local/software/jdk1.8.0_251
export CLASSPATH=${JAVA_HOME}/lib
export PATH=$PATH:${JAVA_HOME}/bin
如果出現
![]()
vi /etc/profile修改正確值
輸入export PATH=/usr/bin:/usr/sbin:/bin:/sbin:/usr/X11R6/bin
并進行source /etc/profile 更新
環境變數配置成功

yum -y install gcc 安裝c編譯環境
任意目錄新建build
tar -zxvf glibc-2.19.tar.gz -C ./build 解壓到build檔案夾下
作業系統加鎖使用的pthread_mutex_lock()方法,我們再次方法中列印呼叫的執行緒Id,只要有執行緒呼叫os作業系統加鎖都會被列印,找到對應的方法檔案


添加列印陳述句
頭部需要添加#include <stdio.h>
fprintf(stderr,"tid=%lu\n",pthread_self());
編譯檔案到/usr/lib:
cd glibc-2.19/
mkdir out
cd out
../configure --prefix=/usr --disable-profile --enable-add-ons --with-headers=/usr/include --with-binutils=/user/bin
如果如下報錯

首先下載binutils-2.32.tar.gz上傳

tar -zxvf binutils-2.32.tar.gz
cd binutils-2.32/
./configure --prefix=/usr/local/software/binutils
make && make install
cd /usr/local/binutils/bin/
./ld –v
./as –v //查看版本
mv /usr/bin/ld /usr/bin/ld_back //備份
mv /usr/bin/as /usr/bin/as_back
ln -s /usr/local/binutils/bin/ld /usr/bin/ld //將安裝的binutils映射到系統檔案(創建軟連接)
ln -s /usr/local/binutils/bin/as /usr/bin/as
在將版本低的插件的安裝一遍
例如:python3 bison
yum install python3
yum install bison
直至運行成功

最后執行make && make install編譯成功(最后顯示離開目錄xxx沒有error)
執行java命令列印對應獲取os鎖執行緒id

存在執行緒競爭
public class Example4Start {
Object o = new Object();
static {
System.loadLibrary( "DouFuThreadNative" );
}
public static void main(String[] args) {
System.out.println("xxxxxxxxxxx子路老師xxxxxxxxxxxxxxxxx");
Example4Start example4Start = new Example4Start();
example4Start.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 tid();
public void sync() throws InterruptedException {
synchronized(o) {
//System.out.println(Thread.currentThread().getName());
tid();
}
// System.out.println(Thread.currentThread().getName() + "----xxxxttttxxx");
}
}
將檔案上傳
javac Example4Start.java 編譯成位元組碼檔案
javah Example4Start 編譯native獲取os系統執行緒方法
創建對應獲取os執行緒getThreadId.c檔案
gcc -fPIC -I /usr/local/software/jdk1.8.0_251/include -I /usr/local/software/jdk1.8.0_251/include/linux -shared -o libDouFuThreadNative.so getThreadId.c -pthread 編譯成一個元件libDouFuThreadNative.so

執行java Example4Start 發現競爭會執行os系統的pthread_mutex_lock進行加鎖


執行緒二不參加競爭
public class Example4Start {
Object o = new Object();
static {
System.loadLibrary( "DouFuThreadNative" );
}
public static void main(String[] args) {
System.out.println("xxxxxxxxxxx子路老師xxxxxxxxxxxxxxxxx");
Example4Start example4Start = new Example4Start();
example4Start.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 tid();
public void sync() throws InterruptedException {
synchronized(o) {
//System.out.println(Thread.currentThread().getName());
tid();
}
// System.out.println(Thread.currentThread().getName() + "----xxxxttttxxx");
}
}
重新編譯后執行


發現除了第一次加鎖,后面都沒有獲取操作執行緒鎖
總結:jdk1.6后對鎖進行優化,偏向鎖(無執行緒競爭,不呼叫作業系統函式),重量鎖(執行緒競爭,呼叫作業系統函式)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/229963.html
標籤:其他
上一篇:dockerfile創建鏡像
