1.8暫停線程,1.8暫停

來源:互聯網
上載者:User

1.8暫停線程,1.8暫停

在java中,使用suspend()方法暫停線程,使用resume()方法恢複線程的執行。

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;    }    @Override    public void run() {        while (true) {            i++;        }    }}

執行代碼:

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();        }    }}

執行結果:

從執行的時間來看,新開啟的線程確實發生了暫停(當前線程暫停與啟動的時間與另外開啟的線程是一致的),並且能夠成功的恢複運行狀態。

1.8.2suspend與resume方法的缺點——獨佔:

在使用suspend與resume方法時,可能會導致公用的同步對象的獨佔發生,使得其他線程無法訪問公用同步對象。

獨佔代碼:

public class SynchronizedObject {    synchronized public void printString() {        System.out.println("begin");        if ("a".equals(Thread.currentThread().getName())) {            System.out.println("a線程永遠的暫停了,suspend");            Thread.currentThread().suspend();        }        System.out.println("end");    }}

執行代碼:

public class Main {    public static void main(String[] args) {        try {            final SynchronizedObject object = new SynchronizedObject();            Thread thread1 = new Thread() {                @Override                public void run() {                    object.printString();                }            };            thread1.setName("a");            thread1.start();            Thread.sleep(1000);            Thread thread2 = new Thread() {                @Override                public void run() {                    System.out.println("因為在Thread1中已經暫停了,後面的語句無法執行,所有只列印了begin");                    System.out.println("因為此時Thread1已經進入了線程並且鎖定了方法printString()所以什麼都打不出來");                    System.out.println("這是死結的一種表現");                    object.printString();                }            };            thread2.setName("a");            thread2.start();        } catch (InterruptedException e) {            e.printStackTrace();        }    }}

另一種陷阱式的多線程獨佔問題

線程代碼:

public class Thread2 extends Thread {    private long i = 0L;    @Override    public void run() {        while (true) {            i++;            System.out.println(i);        }    }}

執行代碼:

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();        }    }}

執行結果:

卡在數字後面,並沒有列印出main end。

原因是在於println()方法,查看其源碼會更加清晰:

 

由源碼可以得知,在println內部存在同步鎖,當線程在println()內部停止時,同步鎖就永遠不會釋放,就會導致死結。  

1.8.3suspend與resume方法的缺點——不同步:

使用這兩個方法容易出現資料不同步的情況。

共用資料類:

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);    }}

執行代碼:

public class Main {    public static void main(String[] args) {        try {            final MyObject object = new MyObject();            Thread thread = new Thread() {                @Override                public void run() {                    object.setValue("a","aa");                }            };            thread.setName("a");            thread.start();            Thread.sleep(1000);            Thread thread1 = new Thread() {                @Override                public void run() {                    object.printUsernamePassword();                }            };            thread1.start();        } catch (InterruptedException e) {            e.printStackTrace();        }    }}

執行結果:

 

源碼地址:https://github.com/lilinzhiyu/threadLearning

本文內容是書中內容兼具自己的個人看法所成。可能在個人看法上會有諸多問題(畢竟知識量有限,導致認知也有限),如果讀者覺得有問題請大膽提出,我們可以相互交流、相互學習,歡迎你們的到來,心成意足,等待您的評價。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.