电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

徹底搞懂Java多線程(二)

瀏覽:106日期:2022-08-09 13:15:10
目錄Java中的鎖1.synchronized鎖(jvm層的解決方案,也叫監(jiān)視器鎖)2.手動(dòng)鎖Locksynchronized鎖synchronized使用場(chǎng)景1.使用synchronized來修飾代碼塊(可以給任意的對(duì)象進(jìn)行加鎖操作)2.使用synchronized來修飾靜態(tài)方法(對(duì)當(dāng)前的類進(jìn)行加鎖的操作)3.使用synchronized來修飾普通的方法(對(duì)當(dāng)前類的實(shí)例來進(jìn)行加鎖)synchronized注意事項(xiàng)1.加鎖的時(shí)候一定要使用同一把鎖對(duì)象Lock鎖使用的注意事項(xiàng)公平鎖、非公平鎖synchronzied 和 Lock 的區(qū)別死鎖造成死鎖的四個(gè)條件死鎖的解決方案線程間通信wait/notify機(jī)制的原理notifyAllwait()和sleep()的區(qū)別線程使用wait()的時(shí)候它就會(huì)釋放掉鎖。sleep(0) 和wait(0)的區(qū)別:LockSupport park()/unpark()總結(jié)Java中的鎖

Java中的加鎖操作有兩種:

1.synchronized鎖(jvm層的解決方案,也叫監(jiān)視器鎖)

在操作系統(tǒng)的層面使用的是互斥鎖(mutex lock)

在Java中放在了對(duì)象頭中。

2.手動(dòng)鎖Lock

操作鎖的流程

1.嘗試獲取鎖 2.使用鎖 3.釋放鎖synchronized鎖

package ThreadDeom;/** * user:ypc; * date:2021-06-12; * time: 14:12; */class Counter2 { private static volatile int count = 0; public void increase() {for (int i = 0; i < 10000; i++) { count++;} } public void decrease() {for (int i = 0; i < 10000; i++) { count--;} } public int getCount() {return count; }}public class ThreadDemo19 { public static void main(String[] args) throws InterruptedException {//聲明鎖對(duì)象,任何的對(duì)象都可以作為鎖Object lock = new Object();Counter2 counter2 = new Counter2();Thread thread1 = new Thread(new Runnable() { @Override public void run() {//使用鎖synchronized (lock) { counter2.decrease();} }});Thread thread2 = new Thread(() -> { synchronized (lock) {counter2.increase(); }});thread1.start();thread2.start();thread1.join();thread2.join();System.out.println(counter2.getCount()); }}

結(jié)果是:

徹底搞懂Java多線程(二)

synchronized使用場(chǎng)景1.使用synchronized來修飾代碼塊(可以給任意的對(duì)象進(jìn)行加鎖操作)

public class ThreadDemo19 { public static void main(String[] args) throws InterruptedException {//聲明鎖對(duì)象,任何的對(duì)象都可以作為鎖Object lock = new Object();Counter2 counter2 = new Counter2();Thread thread1 = new Thread(new Runnable() { @Override public void run() {//使用鎖synchronized (lock) { counter2.decrease();} }});Thread thread2 = new Thread(() -> { synchronized (lock) {counter2.increase(); }});thread1.start();thread2.start();thread1.join();thread2.join();System.out.println(counter2.getCount()); }}

徹底搞懂Java多線程(二)

2.使用synchronized來修飾靜態(tài)方法(對(duì)當(dāng)前的類進(jìn)行加鎖的操作)

package ThreadDeom;/** * user:ypc; * date:2021-06-12; * time: 14:02; */class Counter1 { private static volatile int count = 0; public void increase() {for (int i = 0; i < 10000; i++) { count++;} } public void decrease() {for (int i = 0; i < 10000; i++) { count--;} } public int getCount() {return count; }}public class ThreadDemo18 { public static void main(String[] args) throws InterruptedException {Counter1 counter1 = new Counter1();Thread thread1 = new Thread(new Runnable() { @Override public void run() {counter1.decrease(); }});Thread thread2 = new Thread(() -> { counter1.increase();});thread1.start();thread2.start();thread1.join();thread2.join();System.out.println(counter1.getCount()); }}

徹底搞懂Java多線程(二)

3.使用synchronized來修飾普通的方法(對(duì)當(dāng)前類的實(shí)例來進(jìn)行加鎖)

package ThreadDeom;/** * user:ypc; * date:2021-06-12; * time: 14:12; */public class ThreadDemo20 { private static int num = 0; private static final int maxSize = 100000; public static void main(String[] args) throws InterruptedException {ThreadDemo20 threadDemo20 = new ThreadDemo20();Thread thread1 = new Thread(new Runnable() { @Override public void run() {threadDemo20.increase(); }});Thread thread2 = new Thread(new Runnable() { @Override public void run() { threadDemo20. decrease(); }});thread1.start();thread2.start();thread1.join();thread2.join();System.out.println(num); } //給靜態(tài)的方法進(jìn)行加鎖,被加的鎖是當(dāng)前的對(duì)象。// public synchronized static void increase(){ //給普通的方法進(jìn)行加鎖的操作 public synchronized void increase() {for (int i = 0; i < maxSize; i++) { num++;} } // public synchronized static void decrease(){ public synchronized void decrease() {for (int i = 0; i < maxSize; i++) { num--;} }}

徹底搞懂Java多線程(二)

synchronized注意事項(xiàng)1.加鎖的時(shí)候一定要使用同一把鎖對(duì)象

Lock類的使用

也叫手動(dòng)鎖

package ThreadDeom;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;/** * user:ypc; * date:2021-06-12; * time: 18:32; */public class ThreadDemo22 { private static int number = 0; private static final int maxSize = 100000; public static void main(String[] args) {//創(chuàng)建lock鎖對(duì)象,lock是接口,不能實(shí)列化Lock lock = new ReentrantLock();Thread thread1 = new Thread(() -> { for (int i = 0; i < maxSize; i++) {lock.lock();try { number++;} finally { lock.unlock();} }});Thread thread2 = new Thread(() -> { for (int i = 0; i < maxSize; i++) {lock.lock();try { number--;} finally { lock.unlock();} }});System.out.println(number); }}

徹底搞懂Java多線程(二)

Lock鎖使用的注意事項(xiàng)

lock()操作一定要放在try外面

如果放在try的里面:

1.try中拋出了異常,還沒有加鎖就釋放了finally中的鎖的操作了

2.如果放在了try,沒加鎖就釋放了鎖,就會(huì)拋出異常,就會(huì)將業(yè)務(wù)代碼中的異常吞噬掉👇如果一定要放的話,將lock()放在try的第一行。

package ThreadDeom;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;/** * user:ypc; * date:2021-06-12; * time: 18:49; */public class ThreadDemo23 { public static void main(String[] args) {Lock lock = new ReentrantLock();try{ System.out.println(1/0); lock.lock();} finally { lock.unlock();} }}

徹底搞懂Java多線程(二)

公平鎖、非公平鎖

公平鎖的調(diào)度:

一個(gè)線程釋放鎖。

主動(dòng)喚醒“需要得到鎖”的隊(duì)列來得到鎖。

非公平鎖

當(dāng)一個(gè)線程釋放鎖之后,另一個(gè)線程剛好執(zhí)行到獲取鎖的代碼就可以直接獲取鎖。

Java中的所有鎖默認(rèn)都是非公平鎖。

非公平鎖的性能更高。

ReentrantLock可以設(shè)置非公平鎖。

公平鎖

package ThreadDeom;import java.util.concurrent.locks.ReentrantLock;/** * user:ypc; * date:2021-06-12; * time: 19:22; */public class ThreadDemo24 { public static void main(String[] args) throws InterruptedException {ReentrantLock reentrantLock = new ReentrantLock();Thread thread1 = new Thread(() -> { for (int i = 0; i < 100; i++) {reentrantLock.lock();try { System.out.println('thread1');} finally { reentrantLock.unlock();} }});Thread thread2 = new Thread(() -> { for (int i = 0; i < 100; i++) {reentrantLock.lock();try { System.out.println('thread2');} finally { reentrantLock.unlock();} }});Thread.sleep(100);thread1.start();thread2.start(); }}

打印的結(jié)果是無序的

徹底搞懂Java多線程(二)

如果設(shè)置為公平鎖:👇

徹底搞懂Java多線程(二)

徹底搞懂Java多線程(二)

thread1和thread2 交替輸出

synchronzied 和 Lock 的區(qū)別

1.synchronzied可以自動(dòng)的進(jìn)行加鎖和釋放鎖,而Lock需要手動(dòng)的加鎖、釋放鎖。

2.Lock是Java層面的鎖實(shí)現(xiàn),而synchronzied 是JVM層面鎖的實(shí)現(xiàn)

3.synchronzed 即可以修飾代碼塊,又可以修飾普通方法和靜態(tài)的方法,而Lock 只能修飾代碼塊

4.synchronized 實(shí)現(xiàn)的是 非公平的鎖,而Lock 可以實(shí)現(xiàn)公平鎖。

5.lock的靈活性更高

死鎖

在兩個(gè)或兩個(gè)以上的線程運(yùn)行中,因?yàn)橘Y源的搶占而造成線程一直等待的問題。看👇:

package ThreadDeom;/** * user:ypc; * date:2021-06-12; * time: 19:48; */public class ThreadDemo25 { public static void main(String[] args) throws InterruptedException {Object lockA = new Object();Object lockB = new Object();Thread thread1 = new Thread(() -> { synchronized (lockA) {System.out.println(Thread.currentThread().getName() + '獲取到lockA');//讓線程2獲取lockBtry { Thread.sleep(1000);} catch (InterruptedException e) { e.printStackTrace();}synchronized (lockB) { System.out.println(Thread.currentThread().getName() + '獲取到lockB');} }});Thread thread2 = new Thread(new Runnable() { @Override public void run() {//線程2獲取資源Bsynchronized (lockB) { System.out.println(Thread.currentThread().getName() + '獲取到lockB'); //讓線程1先獲取到鎖lockA try {Thread.sleep(1000); } catch (InterruptedException e) {e.printStackTrace(); } synchronized (lockA) {System.out.println(Thread.currentThread().getName() + '獲取到lockA'); }} }});thread1.start();thread2.start(); }}

這就造成了死鎖

徹底搞懂Java多線程(二)

造成死鎖的四個(gè)條件

1.互斥條件:

當(dāng)資源被一個(gè)線程擁有之后,就不能被其它的線程擁有了

2.擁有請(qǐng)求條件:

當(dāng)一個(gè)線程擁有了一個(gè)資源之后,又試圖請(qǐng)求另一個(gè)資源。

3.不可剝奪條件:

當(dāng)一個(gè)線程擁有了一個(gè)資源之后,如果不是這個(gè)線程主動(dòng)的釋放資源,其他線程就不能擁有這個(gè)線程。

4.環(huán)路等待條件:

兩個(gè)或兩個(gè)以上的線程擁有了資源之后,試圖獲取對(duì)方的資源的時(shí)候形成了一個(gè)環(huán)路。

死鎖的解決方案

解決請(qǐng)求擁有和環(huán)路等待。

最有效的解決方案就是控制加鎖的順序。

package ThreadDeom;/** * user:ypc; * date:2021-06-12; * time: 20:25; */public class ThreadDemo26 { public static void main(String[] args) throws InterruptedException {Object lockA = new Object();Object lockB = new Object();Thread thread1 = new Thread(() -> { synchronized (lockA) {System.out.println(Thread.currentThread().getName() + '獲取到lockA');//讓線程2獲取lockBtry { Thread.sleep(1000);} catch (InterruptedException e) { e.printStackTrace();}synchronized (lockB) { System.out.println(Thread.currentThread().getName() + '獲取到lockB');} }});Thread thread2 = new Thread(new Runnable() { @Override public void run() {synchronized (lockA) { System.out.println(Thread.currentThread().getName() + '獲取到lockA'); try {Thread.sleep(1000); } catch (InterruptedException e) {e.printStackTrace(); } synchronized (lockB) {System.out.println(Thread.currentThread().getName() + '獲取到lockB'); }} }});thread1.start();thread2.start(); }}

徹底搞懂Java多線程(二)

線程間通信

線程之間的通訊是指在一個(gè)線程中的操作可以影響另一個(gè)線程。

wait/notify機(jī)制的原理

擁有相同鎖的線程之間才能使用wait/notify機(jī)制。

wait()是Object()的方法,它的作用是是當(dāng)前執(zhí)行wait()方法的線程等待,在wati()所在的代碼出停止執(zhí)行,并釋放鎖,直到接到通知或者被中斷為止。即在調(diào)用wait()的方法之前,線程必需先獲取到對(duì)象級(jí)別的鎖,也就是只能在同步方法或者同步塊中使用wait()方法。

如果在使用wait()方法之前線程沒有獲得相應(yīng)的鎖,那么程序在執(zhí)行時(shí)就會(huì)拋出異常。

notify()方法要在同步方法或者同步塊中執(zhí)行,即在調(diào)用notify()方法之前,線程必需要先獲取到鎖對(duì)象。如果線程沒有持有鎖對(duì)象的話,那么也會(huì)拋出異常。該方法用來通知可能在等待該鎖的其它線程,如果有多個(gè)線程,那么則按照?qǐng)?zhí)行wait()方法的順序來對(duì)處于wait()方法的線程發(fā)出通知,并使該線程重新獲取鎖。執(zhí)行notify()方法之后,當(dāng)前線程不會(huì)馬上釋放鎖,處于wait()狀態(tài)的線程也不會(huì)立馬得到這個(gè)對(duì)象鎖。而是要等notify的synchronized同步區(qū)域執(zhí)行完成之后才會(huì)釋放鎖,處于wait()狀態(tài)的線程才會(huì)得到鎖對(duì)象。

總結(jié):wait()方法用于讓線程停止運(yùn)行,而notify()方法用于通知暫停的線程繼續(xù)運(yùn)行。

在使用wait()或者notify()方法之前沒有對(duì)象鎖,就會(huì)報(bào)異常👇:

lock.notify();

徹底搞懂Java多線程(二)

正確的使用之后

package ThreadDeom;/** * user:ypc; * date:2021-06-12; * time: 21:11; */public class ThreadDemo27 { //設(shè)置鎖對(duì)象 private static Object lock = new Object(); public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(new Runnable() { @Override public void run() {synchronized (lock) { System.out.println('在wait()'); try {lock.wait(); } catch (InterruptedException e) {e.printStackTrace(); } System.out.println('被notify()喚醒之后');} }});thread.start();Thread.sleep(1000);synchronized (lock) { lock.notify();} }}

徹底搞懂Java多線程(二)

注意:使用wait()方法的時(shí)候一定要和線程的鎖對(duì)象是一個(gè)鎖。

notifyAll

在多線程的情況下使用notify()方法只可以喚醒一個(gè)線程👇

徹底搞懂Java多線程(二)

package ThreadDeom;/** * user:ypc; * date:2021-06-13; * time: 8:06; */public class ThreadDemo28 { //設(shè)置鎖對(duì)象 private static Object lock = new Object(); public static void main(String[] args) throws InterruptedException {Thread thread1 = new Thread(new Runnable() { @Override public void run() {synchronized (lock) { System.out.println('thread1在wait()'); try {lock.wait(); } catch (InterruptedException e) {e.printStackTrace(); } System.out.println('thread1被notify()喚醒之后');} }});Thread thread2 = new Thread(() -> { synchronized (lock) {System.out.println('thread2在wait()');try { lock.wait();} catch (InterruptedException e) { e.printStackTrace();}System.out.println('thread2被notify()喚醒之后'); }});Thread thread3 = new Thread(new Runnable() { @Override public void run() {synchronized (lock) { System.out.println('thread3在wait()'); try {lock.wait(); } catch (InterruptedException e) {e.printStackTrace(); } System.out.println('thread3被notify()喚醒之后');} }});thread1.start();thread2.start();thread3.start();Thread.sleep(1000);synchronized (lock) { System.out.println('主線程調(diào)用notify()之后'); lock.notify();} }}

那么如果使用notifyAll()方法呢?

徹底搞懂Java多線程(二)

可以看到所有的線程都被喚醒了

徹底搞懂Java多線程(二)

那么使用notify()喚醒的線程有沒有什么順序呢?

使用notify()喚醒線程的順序是正序、倒序、還是隨機(jī)的,這取決與JVM的具體實(shí)現(xiàn),并不是所有的JVM在執(zhí)行notify()時(shí)都是按照wait()的執(zhí)行順序進(jìn)行喚醒的,也不是所有的notidyAll()都是按照wait()方法的倒序進(jìn)行喚醒的,這取決于JVM的具體實(shí)現(xiàn)。

wait()和notify()不能喚醒指定的線程。

wait()和sleep()的區(qū)別

也可以讓wait()等待指定的時(shí)間,如果超過給定的時(shí)間,wait()不會(huì)無限期的等待下去.

徹底搞懂Java多線程(二)

沒有被notify()喚醒,過了1000毫秒之后會(huì)自動(dòng)停止。

徹底搞懂Java多線程(二)

wait()在不傳入任何參數(shù)的時(shí)候,線程會(huì)進(jìn)入waiting 的狀態(tài),而在wait()中加入一個(gè)大于0的參數(shù)的時(shí)候,線程會(huì)進(jìn)入time_wating的狀態(tài)。

sleep()和wait()的區(qū)別 : 線程在sleep()的時(shí)候是不會(huì)釋放鎖的,而執(zhí)行wait()的時(shí)候它就會(huì)釋放鎖。👇:

package ThreadDeom;import jdk.nashorn.internal.ir.Block;/** * user:ypc; * date:2021-06-13; * time: 8:45; */public class ThreadDemo29 { private static Object lock = new Object(); public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(new Runnable() { @Override public void run() {synchronized (lock) { try {System.out.println('thread獲取到了鎖');//如果sleep釋放鎖的話,會(huì)在thread獲取到了鎖和thread釋放了鎖之間打印Thread.sleep(3000); } catch (InterruptedException e) {e.printStackTrace(); }}System.out.println('thread釋放了鎖'); }});thread.start();//讓thread 先獲取到鎖Thread.sleep(1000);synchronized (lock) { System.out.println('主線程獲取到了鎖');} }}

徹底搞懂Java多線程(二)

可以看到線程在sleep()的時(shí)候,線程是不會(huì)釋放鎖的。再來看看wait()方法👇:

徹底搞懂Java多線程(二)

徹底搞懂Java多線程(二)

線程使用wait()的時(shí)候它就會(huì)釋放掉鎖。

1.wait()和sleep()都是讓線程進(jìn)行休眠的

2.wait()和sleep()方法都有可能在執(zhí)行的過程接收到線程終止的通知

3.wait()必須和synchronzied一起使用,而sleep()不用。

4.wait()會(huì)釋放鎖,而sleep()不會(huì)釋放鎖。

5.wait()時(shí)Object的方法,而sleep()時(shí)Thread的方法。

6.默認(rèn)情況下,wait()不傳任何的參數(shù)的情況下,wait()會(huì)進(jìn)入waiting的狀態(tài),如果傳遞了參數(shù),wait()會(huì)進(jìn)入time_waiting的狀態(tài)。而sleep()進(jìn)入的是time_waiting的狀態(tài)。

sleep(0) 和wait(0)的區(qū)別:

1.sleep(0)表示0毫秒之后繼續(xù)執(zhí)行,而wait(0)表示線程會(huì)一直休眠下去wait(0)和wait()是一樣的,wait()的源碼就是調(diào)用了wait(0)方法。

2.sleep(0)表示重新出發(fā)一次CPU的競(jìng)爭(zhēng)。

為什么wait()會(huì)釋放鎖,而sleep()不會(huì)釋放鎖?

sleep()需要傳遞一個(gè)最大的等待時(shí)間,也就是說sleep()是可控的,而wait()是不可以傳遞參數(shù)的,從設(shè)計(jì)的層面來說,如果讓wait()一直持有所得話,那么線程就可能一直阻塞。

為什么wait()是Object的方法,而sleep()是線程的方法?

wait()需要操作鎖,而鎖是屬于對(duì)象級(jí)別的,所有的鎖都是放在對(duì)象頭中的,它不是線程級(jí)別的,一個(gè)線程可以有多把的鎖,為了靈活,就將wait()放在Object中了。

LockSupport park()/unpark()

使用LockSupport可以解決wait()/notify()隨機(jī)喚醒的問題。

package ThreadDeom;import java.util.concurrent.locks.LockSupport;/** * user:ypc; * date:2021-06-13; * time: 9:36; */public class ThreadDemo30 { public static void main(String[] args) {Thread thread1 = new Thread(new Runnable() { @Override public void run() {//讓線程休眠LockSupport.park();System.out.println('unPark()了thread1'); }});Thread thread2 = new Thread(() -> { LockSupport.park(); System.out.println('unPark()了thread2');});Thread thread3 = new Thread() { @Override public void run() {LockSupport.park();System.out.println('unPark()了thread3'); }};thread1.start();thread2.start();thread3.start();LockSupport.unpark(thread1);LockSupport.unpark(thread2); }}

徹底搞懂Java多線程(二)

總結(jié)

本篇文章就到這里了,希望可以幫助到你,也希望您能夠多多關(guān)注好吧啦網(wǎng)的更多內(nèi)容!

標(biāo)簽: Java
相關(guān)文章:
主站蜘蛛池模板: 标策网-专注公司商业知识服务、助力企业发展 | 游动电流仪-流通式浊度分析仪-杰普仪器(上海)有限公司 | 厦门网站建设_厦门网站设计_小程序开发_网站制作公司【麦格科技】 | 新疆散热器,新疆暖气片,新疆电锅炉,光耀暖通公司 | 成都茶楼装修公司 - 会所设计/KTV装修 - 成都朗煜装饰公司 | 杭州中央空调维修_冷却塔/新风机柜/热水器/锅炉除垢清洗_除垢剂_风机盘管_冷凝器清洗-杭州亿诺能源有限公司 | 新能源汽车电机定转子合装机 - 电机维修设备 - 睿望达 | 热回收盐水机组-反应釜冷水机组-高低温冷水机组-北京蓝海神骏科技有限公司 | 工业铝型材生产厂家_铝合金型材配件批发精加工定制厂商 - 上海岐易铝业 | 比士亚-专业恒温恒湿酒窖,酒柜,雪茄柜的设计定制 | ◆大型吹塑加工|吹塑加工|吹塑代加工|吹塑加工厂|吹塑设备|滚塑加工|滚塑代加工-莱力奇塑业有限公司 | 酒水灌装机-白酒灌装机-酒精果酒酱油醋灌装设备_青州惠联灌装机械 | 圣才学习网-考研考证学习平台,提供万种考研考证电子书、题库、视频课程等考试资料 | 泥沙分离_泥沙分离设备_泥砂分离机_洛阳隆中重工机械有限公司 | 安全光栅|射频导纳物位开关|音叉料位计|雷达液位计|两级跑偏开关|双向拉绳开关-山东卓信机械有限公司 | 二手注塑机回收_旧注塑机回收_二手注塑机买卖 - 大鑫二手注塑机 二手光谱仪维修-德国OBLF光谱仪|进口斯派克光谱仪-热电ARL光谱仪-意大利GNR光谱仪-永晖检测 | 高扬程排污泵_隔膜泵_磁力泵_节能自吸离心水泵厂家-【上海博洋】 | 除湿机|工业除湿机|抽湿器|大型地下室车间仓库吊顶防爆除湿机|抽湿烘干房|新风除湿机|调温/降温除湿机|恒温恒湿机|加湿机-杭州川田电器有限公司 | 磁力抛光机_磁力研磨机_磁力去毛刺机_精密五金零件抛光设备厂家-冠古科技 | 微波消解仪器_智能微波消解仪报价_高压微波消解仪厂家_那艾 | 澳威全屋定制官网|极简衣柜十大品牌|衣柜加盟代理|全屋定制招商 百度爱采购运营研究社社群-店铺托管-爱采购代运营-良言多米网络公司 | 非甲烷总烃分析仪|环控百科 | 澳洁干洗店加盟-洗衣店干洗连锁「澳洁干洗免费一对一贴心服务」 干洗加盟网-洗衣店品牌排行-干洗设备价格-干洗连锁加盟指南 | 新型锤式破碎机_新型圆锥式_新型颚式破碎机_反击式打沙机_锤式制砂机_青州建源机械 | EDLC超级法拉电容器_LIC锂离子超级电容_超级电容模组_软包单体电容电池_轴向薄膜电力电容器_深圳佳名兴电容有限公司_JMX专注中高端品牌电容生产厂家 | 三佳互联一站式网站建设服务|网站开发|网站设计|网站搭建服务商 赛默飞Thermo veritiproPCR仪|ProFlex3 x 32PCR系统|Countess3细胞计数仪|371|3111二氧化碳培养箱|Mirco17R|Mirco21R离心机|仟诺生物 | 北京翻译公司_同传翻译_字幕翻译_合同翻译_英语陪同翻译_影视翻译_翻译盖章-译铭信息 | 心得体会网_心得体会格式范文模板 | ph计,实验室ph计,台式ph计,实验室酸度计,台式酸度计 | 旋振筛|圆形摇摆筛|直线振动筛|滚筒筛|压榨机|河南天众机械设备有限公司 | 浙江建筑资质代办_二级房建_市政_电力_安许_劳务资质办理公司 | 齿轮减速机_齿轮减速电机-VEMT蜗轮蜗杆减速机马达生产厂家瓦玛特传动瑞环机电 | 山东包装,山东印刷厂,济南印刷厂-济南富丽彩印刷有限公司 | 臭氧发生器_臭氧消毒机 - 【同林品牌 实力厂家】 | 中式装修设计_全屋定制家具_实木仿古门窗花格厂家-喜迎门 | 上海宿田自动化设备有限公司-双面/平面/单面贴标机 | 金属雕花板_厂家直销_价格低-山东慧诚建筑材料有限公司 | 直流电能表-充电桩电能表-导轨式电能表-智能电能表-浙江科为电气有限公司 | 杭州顺源过滤机械有限公司官网-压滤机_板框压滤机_厢式隔膜压滤机厂家 | 哈希余氯测定仪,分光光度计,ph在线监测仪,浊度测定仪,试剂-上海京灿精密机械有限公司 | 护腰带生产厂家_磁石_医用_热压护腰_登山护膝_背姿矫正带_保健护具_医疗护具-衡水港盛 |