Java中多线程阻塞和唤醒的示例代码
本文主要向大家分享了Java多线程中的阻塞与唤醒的相关内容,通过这篇文章大家可以大致了解到进入线程阻塞状态和可执行状态的方法,需要的朋友可以了解下。
java线程的阻塞及唤醒
1. sleep() 方法:
sleep(…毫秒),指定以毫秒为单位的时间,使线程在该时间内进入线程阻塞状态,期间得不到cpu的时间片,等到时间过去了,线程重新进入可执行状态。(暂停线程,不会释放锁)
//测试sleep()方法 class Thread7 implements Runnable{ @Override public void run() { for(int i=0;i<50;i++){ System.out.println(Thread.currentThread().getName()+"num="+i); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } } } class Thread8 implements Runnable{ @Override public void run() { for(int i=0;i<1000;i++){ System.out.println(Thread.currentThread().getName()+"num="+i); } } } public static void main(String[] args) { /* * 测试线程阻塞 */ //测试sleep()方法 Thread7 t7=new Thread7(); Thread8 t8=new Thread8(); Thread t81=new Thread(t8, "饺子"); Thread t71=new Thread(t7, "包子"); Thread t72=new Thread(t7, "面包"); t71.start(); t81.start(); t72.start(); }
2.suspend() 和 resume() 方法:。
挂起和唤醒线程,suspend()使线程进入阻塞状态,只有对应的resume()被调用的时候,线程才会进入可执行状态。(不建议用,容易发生死锁)
//测试suspend()和resume()方法 class Thread9 implements Runnable{ @Override public void run() { for(long i=0;i<500000000;i++){ System.out.println(Thread.currentThread().getName()+" num= "+i); } } } public static void main(String[] args) { //测试suspend和resume Thread9 t9=new Thread9(); Thread t91=new Thread(t9,"包子"); t91.start(); try { Thread.sleep(2000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } t91.suspend(); try { Thread.sleep(2000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } t91.resume(); }
(在控制台打印输出的时候,会停顿2秒钟,然后再继续打印。)
3. yield() 方法:
会使的线程放弃当前分得的cpu时间片,但此时线程任然处于可执行状态,随时可以再次分得cpu时间片。yield()方法只能使同优先级的线程有执行的机会。调用 yield() 的效果等价于调度程序认为该线程已执行了足够的时间从而转到另一个线程。(暂停当前正在执行的线程,并执行其他线程,且让出的时间不可知)
//测试yield()方法 class Thread10 implements Runnable{ @Override public void run() { for(int i=0;i<100;i++){ System.out.println(Thread.currentThread().getName()+" num= "+i); if(i==33){ Thread.yield(); } } } } public static void main(String[] args) { //测试yield Thread10 t10 =new Thread10(); Thread t101=new Thread(t10, "包子"); Thread t102=new Thread(t10, "面包"); t101.start(); t102.start(); } /* 运行结果为: …… 包子 num= 24 包子 num= 25 包子 num= 26 包子 num= 27 包子 num= 28 包子 num= 29 包子 num= 30 包子 num= 31 包子 num= 32 包子 num= 33 面包 num= 0 面包 num= 1 面包 num= 2 面包 num= 3 …… 面包 num= 30 面包 num= 31 面包 num= 32 面包 num= 33 包子 num= 34 包子 num= 35 包子 num= 36 包子 num= 37 包子 num= 38 …… */
(可以看到,当数字为33时,都发生了交替。)
4.wait() 和 notify() 方法:
两个方法搭配使用,wait()使线程进入阻塞状态,调用notify()时,线程进入可执行状态。wait()内可加或不加参数,加参数时是以毫秒为单位,当到了指定时间或调用notify()方法时,进入可执行状态。(属于Object类,而不属于Thread类,wait( )会先释放锁住的对象,然后再执行等待的动作。由于wait( )所等待的对象必须先锁住,因此,它只能用在同步化程序段或者同步化方法内,否则,会抛出异常IllegalMonitorStateException.)
//测试wait()和notify()方法 //用生产者和消费者模式模拟这一过程 /*消费者 */ class Consumer implements Runnable { private Vector obj; public Consumer(Vector v) { this.obj = v; } public void run() { synchronized (obj) { while (true) { try { if (obj.size() == 0) { obj.wait(); } System.out.println("消费者:我要买面包。"); System.out.println("面包数: " + obj.size()); obj.clear(); obj.notify(); } catch (Exception e) { e.printStackTrace(); } } } } } /* 生产者 */ class Producter implements Runnable { private Vector obj; public Producter(Vector v) { this.obj = v; } public void run() { synchronized (obj) { while (true) { try { if (obj.size() != 0) { obj.wait(); } obj.add(new String("面包")); obj.notify(); System.out.println("生产者:面包做好了。"); Thread.sleep(500); } catch (Exception e) { e.printStackTrace(); } } } } } public static void main(String[] args) { //测试wait()和notify() Vector obj = new Vector(); Thread consumer = new Thread(new Consumer(obj)); Thread producter = new Thread(new Producter(obj)); consumer.start(); producter.start(); }
5.join()方法
也叫线程加入。是当前线程A调用另一个线程B的join()方法,当前线程转A入阻塞状态,直到线程B运行结束,线程A才由阻塞状态转为可执行状态。
//测试join class Thread11 implements Runnable{ @Override public void run() { System.out.println("Start Progress."); try { for(int i=0;i<5;i++){ System.out.println("Thread11线程 : "+i); Thread.sleep(1000); } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("End Progress."); } } public static void main(String[] args) { //测试join Thread11 t11=new Thread11(); Thread t111=new Thread(t11); t111.start(); try { t111.join(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("hi,I'm Main线程"); } /* 运行结果为: Start Progress. Thread11线程 : 0 Thread11线程 : 1 Thread11线程 : 2 Thread11线程 : 3 Thread11线程 : 4 End Progress. hi,I'm Main线程 */
总结
Atas ialah kandungan terperinci Java中多线程阻塞和唤醒的示例代码. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas

Panduan untuk Square Root di Java. Di sini kita membincangkan cara Square Root berfungsi di Java dengan contoh dan pelaksanaan kodnya masing-masing.

Panduan Nombor Sempurna di Jawa. Di sini kita membincangkan Definisi, Bagaimana untuk menyemak nombor Perfect dalam Java?, contoh dengan pelaksanaan kod.

Panduan untuk Penjana Nombor Rawak di Jawa. Di sini kita membincangkan Fungsi dalam Java dengan contoh dan dua Penjana berbeza dengan contoh lain.

Panduan untuk Weka di Jawa. Di sini kita membincangkan Pengenalan, cara menggunakan weka java, jenis platform, dan kelebihan dengan contoh.

Panduan untuk Nombor Armstrong di Jawa. Di sini kita membincangkan pengenalan kepada nombor Armstrong di java bersama-sama dengan beberapa kod.

Panduan untuk Nombor Smith di Jawa. Di sini kita membincangkan Definisi, Bagaimana untuk menyemak nombor smith di Jawa? contoh dengan pelaksanaan kod.

Dalam artikel ini, kami telah menyimpan Soalan Temuduga Spring Java yang paling banyak ditanya dengan jawapan terperinci mereka. Supaya anda boleh memecahkan temuduga.

Java 8 memperkenalkan API Stream, menyediakan cara yang kuat dan ekspresif untuk memproses koleksi data. Walau bagaimanapun, soalan biasa apabila menggunakan aliran adalah: bagaimana untuk memecahkan atau kembali dari operasi foreach? Gelung tradisional membolehkan gangguan awal atau pulangan, tetapi kaedah Foreach Stream tidak menyokong secara langsung kaedah ini. Artikel ini akan menerangkan sebab -sebab dan meneroka kaedah alternatif untuk melaksanakan penamatan pramatang dalam sistem pemprosesan aliran. Bacaan Lanjut: Penambahbaikan API Java Stream Memahami aliran aliran Kaedah Foreach adalah operasi terminal yang melakukan satu operasi pada setiap elemen dalam aliran. Niat reka bentuknya adalah
