线程状态图:
注意:线程休眠sleep并不会释放锁,即当前的cpu仍然调度该线程
礼让不一定成功。
package com.Thread; //线程礼让 public class Test_Yield implements Runnable{ @Override public void run(){ System.out.println(Thread.currentThread().getName()+"正在执行"); //线程礼让 不一定成功,看cpu心情 Thread.yield(); System.out.println(Thread.currentThread().getName()+"执行完毕"); } public static void main(String[] args) { Test_Yield test_yield=new Test_Yield(); new Thread(test_yield,"线程a").start(); new Thread(test_yield,"线程b").start(); } }
package com.Thread; public class Test_Join implements Runnable{ @Override public void run(){ for(int i=0;i<10;i++){ System.out.println((i+1)+"---vip来了,你们都给我让路"); } } public static void main(String[] args) { Test_Join test_join=new Test_Join(); Thread thread=new Thread(test_join); thread.start(); for(int j=0;j<5;j++){ if(j==3){ try { //等待子线程thread执行完后 再执行主线程 thread.join(); }catch (InterruptedException e){ e.getMessage(); } } System.out.println("main---"+(j+1)); } } }
注意:一定要先设置优先级再启动。
优先级高的不一定先执行,但是大多数情况优先级高的会先执行。通过优先级你可以将需要先执行的代码块设置成高优先级。
通过Thread.setDaemon(false)设置为用户线程
通过Thread.setDaemon(true)设置为守护线程
守护线程的定义:
是指在程序运行的时候在后台提供一种通用服务的线程,比如垃圾回收线程就是一个很称职的守护者,并且这种线程并不属于程序中不可或缺的部分。因此,当所有的非守护线程结束时,程序也就终止了,同时会杀死进程中的所有守护线程。反过来说,只要任何非守护线程还在运行,程序就不会终止。
用户线程定义
指不需要内核支持而在用户程序中实现的线程,其不依赖于操作系统核心,应用进程利用线程库提供创建、同步、调度和管理线程的函数来控制用户线程。这种线程甚至在象 DOS 这样的操作系统中也可实现,但线程的调度需要用户程序完成,这有些类似 Windows 3.x 的协作式多任务。
package com.Thread; public class Guard_Thread{ public static void main(String[] args) { People people=new People(); God god=new God(); Thread p=new Thread(people); Thread God=new Thread(god); //将线程God设置为守护线程 虚拟机不必等待守护线程执行完毕 God.setDaemon(true); p.start(); God.start(); } } class People implements Runnable{ @Override public void run(){ for(int i=1;i<=36500;i++){ System.out.println("今天第是"+i+"天"); } } } class God implements Runnable{ @Override public void run(){ while (true){ System.out.println("上帝God"); } } }
测试JUC安全类型集合
如下示例:
package com.DeadLock; public class DeadLock{ public static void main(String[] args) { Makeup girl1=new Makeup(0,"灰姑凉"); Makeup girl2=new Makeup(1,"白雪公主"); girl1.start(); girl2.start(); } } //口红 class lipstick{ } //化妆 class Mirror{ } class Makeup extends Thread{ //口红 static lipstick l=new lipstick(); //镜子 static Mirror mirror=new Mirror(); int choice; String girlName; Makeup(int choice,String girlName){ this.choice=choice; this.girlName=girlName; } @Override public void run(){ //化妆 try{ makeup(); }catch (InterruptedException e){ e.printStackTrace(); } } //化妆的方法 互相持有对方的锁,需要拿到对方的资源 private void makeup() throws InterruptedException{ if(choice==0){ synchronized (l){ //获得口红的锁 System.out.println(this.girlName+"获得口红的锁"); Thread.sleep(1000); //获得镜子的锁 // synchronized (mirror){ // System.out.println(this.girlName+"获得镜子的锁"); // } } //拿到外面来就不会死锁了 synchronized (mirror){ System.out.println(this.girlName+"获得镜子的锁"); } }else { synchronized (mirror){ //获得口红的锁 System.out.println(this.girlName+"获得镜子的锁"); Thread.sleep(1000); //获得镜子的锁 // synchronized (l){ // System.out.println(this.girlName+"获得口红的锁"); // } } //拿到外面来就不会死锁了 synchronized (l){ System.out.println(this.girlName+"获得口红的锁"); } } } }
示例代码:
package com.DeadLock; import java.util.concurrent.locks.ReentrantLock; //ReentrantLock:可重入锁 public class TestLock { public static void main(String[] args) { TestLock2 testLock2=new TestLock2(); new Thread(testLock2).start(); new Thread(testLock2).start(); new Thread(testLock2).start(); } } class TestLock2 implements Runnable{ private int tickesNum=10; //定义Lock锁 private final ReentrantLock Lock=new ReentrantLock(); @Override public void run(){ while (true){ try { Lock.lock(); //加锁 if(tickesNum>0){ try{ Thread.sleep(1000); } catch (InterruptedException e){ e.printStackTrace(); } System.out.println(tickesNum--); }else{ return; } }finally { Lock.unlock(); //解锁 } } } }
synchronized域Lock的对比