1.8暂停线程
在java中,使用suspend()方法暫停線程,使用resume()方法恢復(fù)線程的執(zhí)行。
1.8.1suspend與resume的使用:
線程代碼:
public class Thread1 extends Thread {private long i = 0L;public long getI() {return i;}public void setI(long i) {this.i = i;}@Overridepublic void run() {while (true) {i++;}} }執(zhí)行代碼:
public class Main {public static void main(String[] args) {try {Thread1 thread = new Thread1();thread.start();Thread.sleep(1000);//A段 thread.suspend();System.out.println("A = " + System.currentTimeMillis() + " I = " +thread.getI());//B段 thread.resume();Thread.sleep(1000);//C段 thread.suspend();System.out.println("B = " + System.currentTimeMillis() + " I = " + thread.getI());Thread.sleep(5000);System.out.println("B = " + System.currentTimeMillis() + "I = " + thread.getI());} catch (InterruptedException e) {e.printStackTrace();}} }執(zhí)行結(jié)果:
從執(zhí)行的時(shí)間來(lái)看,新開(kāi)啟的線程確實(shí)發(fā)生了暫停(當(dāng)前線程暫停與啟動(dòng)的時(shí)間與另外開(kāi)啟的線程是一致的),并且能夠成功的恢復(fù)運(yùn)行狀態(tài)。
1.8.2suspend與resume方法的缺點(diǎn)——獨(dú)占:
在使用suspend與resume方法時(shí),可能會(huì)導(dǎo)致公共的同步對(duì)象的獨(dú)占發(fā)生,使得其他線程無(wú)法訪問(wèn)公共同步對(duì)象。
獨(dú)占代碼:
public class SynchronizedObject {synchronized public void printString() {System.out.println("begin");if ("a".equals(Thread.currentThread().getName())) {System.out.println("a線程永遠(yuǎn)的暫停了,suspend");Thread.currentThread().suspend();}System.out.println("end");} }執(zhí)行代碼:
public class Main {public static void main(String[] args) {try {final SynchronizedObject object = new SynchronizedObject();Thread thread1 = new Thread() {@Overridepublic void run() {object.printString();}};thread1.setName("a");thread1.start();Thread.sleep(1000);Thread thread2 = new Thread() {@Overridepublic void run() {System.out.println("因?yàn)樵赥hread1中已經(jīng)暫停了,后面的語(yǔ)句無(wú)法執(zhí)行,所有只打印了begin");System.out.println("因?yàn)榇藭r(shí)Thread1已經(jīng)進(jìn)入了線程并且鎖定了方法printString()所以什么都打不出來(lái)");System.out.println("這是死鎖的一種表現(xiàn)");object.printString();}};thread2.setName("a");thread2.start();} catch (InterruptedException e) {e.printStackTrace();}} }另一種陷阱式的多線程獨(dú)占問(wèn)題
線程代碼:
public class Thread2 extends Thread {private long i = 0L;@Overridepublic void run() {while (true) {i++;System.out.println(i);}} }執(zhí)行代碼:
public class Main {public static void main(String[] args) {try {Thread2 thread = new Thread2();thread.start();Thread.sleep(1000);thread.suspend();System.out.println("main end");} catch (InterruptedException e) {e.printStackTrace();}} }執(zhí)行結(jié)果:
卡在數(shù)字后面,并沒(méi)有打印出main end。
原因是在于println()方法,查看其源碼會(huì)更加清晰:
?
由源碼可以得知,在println內(nèi)部存在同步鎖,當(dāng)線程在println()內(nèi)部停止時(shí),同步鎖就永遠(yuǎn)不會(huì)釋放,就會(huì)導(dǎo)致死鎖。
1.8.3suspend與resume方法的缺點(diǎn)——不同步:
使用這兩個(gè)方法容易出現(xiàn)數(shù)據(jù)不同步的情況。
共享數(shù)據(jù)類:
public class MyObject {private String username = "1";private String password = "11";public void setValue(String u,String p) {this.username = u;if("a".equals(Thread.currentThread().getName())) {System.out.println("停止a線程");Thread.currentThread().suspend();}this.password = p;}public void printUsernamePassword() {System.out.println(username + "|||" + password);} }執(zhí)行代碼:
public class Main {public static void main(String[] args) {try {final MyObject object = new MyObject();Thread thread = new Thread() {@Overridepublic void run() {object.setValue("a","aa");}};thread.setName("a");thread.start();Thread.sleep(1000);Thread thread1 = new Thread() {@Overridepublic void run() {object.printUsernamePassword();}};thread1.start();} catch (InterruptedException e) {e.printStackTrace();}} }執(zhí)行結(jié)果:
?
源碼地址:https://github.com/lilinzhiyu/threadLearning
本文內(nèi)容是書(shū)中內(nèi)容兼具自己的個(gè)人看法所成。可能在個(gè)人看法上會(huì)有諸多問(wèn)題(畢竟知識(shí)量有限,導(dǎo)致認(rèn)知也有限),如果讀者覺(jué)得有問(wèn)題請(qǐng)大膽提出,我們可以相互交流、相互學(xué)習(xí),歡迎你們的到來(lái),心成意足,等待您的評(píng)價(jià)。
?
轉(zhuǎn)載于:https://www.cnblogs.com/lilinzhiyu/p/7986231.html
總結(jié)
- 上一篇: go语言入门(三)
- 下一篇: webstorm 代码提示