------------恢复内容开始------------
在java中 线程使用有两种方式
1.继承Thread类,重写run方法
public class test1 { public static void main(String[] args) { //获取cpu 数 Runtime runtime=Runtime.getRuntime(); int num=runtime.availableProcessors(); System.out.println(num); Cat cat=new Cat(); cat.start(); //启动线程 } } class Cat extends Thread{ @Override public void run() { System.out.println("我是小猫咪"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } }
2.实现Runnable接口,重写run方法
public class Thread02 { public static void main(String[] args) { Dog dog=new Dog(); Thread thread=new Thread(dog); thread.start(); } } class Dog implements Runnable{ @Override public void run() { int num=0; while (true){ try { Thread.sleep(1000); System.out.println(num+Thread.currentThread().getName()); } catch (InterruptedException e) { e.printStackTrace(); } num++; if(num>20)break; } } }
3.多线程执行售票(会出现线程同步和互斥问题,此处不考虑)
public class Thread03 { public static void main(String[] args) { SellTicket sellTicket=new SellTicket(); Thread thread1=new Thread(sellTicket); thread1.start(); Thread thread2=new Thread(sellTicket); thread2.start(); Thread thread3=new Thread(sellTicket); thread3.start(); } } class SellTicket implements Runnable{ private int ticketNum=100; @Override public void run() { while (true){ if(ticketNum<=0)break; try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"买了一张票,还剩:"+--ticketNum); } } }
线程的结束
1.当线程执行完毕自动结束
2.手动停止线程
public class Thread04 { public static void main(String[] args) throws InterruptedException { Tt tt = new Tt(); tt.start(); Thread.sleep(5*1000); tt.setLoop(false); } } class Tt extends Thread{ private Boolean loop=true; private int num=0; @Override public void run() { while (loop){ try { Thread.sleep(50); System.out.println(Thread.currentThread().getName()+num++ ); } catch (InterruptedException e) { e.printStackTrace(); } } } public void setLoop(Boolean loop){ this.loop=loop; } }
线程常用的方法
线程插队
yield:线程的礼让
join: 线程的插队
package com.xxxx.server.controller.test; public class Thread05 { public static void main(String[] args) throws InterruptedException { T t = new T(); t.start(); for (int i = 0; i < 20; i++) { Thread.sleep(1000); System.out.println("小弟正在吃"+i+"包子"); if(i==5){ t.join(); } } } } class T extends Thread{ @Override public void run() { int num=0; while (true){ try { Thread.sleep(1000); System.out.println("大哥正在吃"+num+"包子"); num++; } catch (InterruptedException e) { e.printStackTrace(); } if(num>=20)break; } } }
守护线程
package com.xxxx.server.controller.test; public class Thread06 { public static void main(String[] args) throws InterruptedException { myDaemonThread myDaemonThread = new myDaemonThread(); myDaemonThread.setDaemon(true); myDaemonThread.start(); for (int i = 0; i < 5; i++) { Thread.sleep(1000); System.out.println("宝宝在吃饭"); } } } class myDaemonThread extends Thread{ @Override public void run() { for (int i = 0; i < 10; i++) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("爸爸妈妈在吃饭"); } } }
线程的生命周期(7个状态)
线程的同步(synchronized)
可以在方法或者代码块上加锁
package com.xxxx.server.controller.test; public class Thread03 { public static void main(String[] args) { SellTicket sellTicket=new SellTicket(); Thread thread1=new Thread(sellTicket); thread1.start(); Thread thread2=new Thread(sellTicket); thread2.start(); Thread thread3=new Thread(sellTicket); thread3.start(); } } class SellTicket implements Runnable{ private int ticketNum=100; Boolean loop=true; @Override public void run() { while (loop){ sell(); } } //线程同步 添加互斥锁 public synchronized void sell(){ if(ticketNum<=0){ System.out.println("票卖完了"); this.loop=false; return; } try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"买了一张票,还剩:"+--ticketNum); } }
上面同步的原理就是互斥锁
加在代码块的方式
线程的死锁
当两个线程互相要抢对方锁的时候,就形成了死锁
释放锁
下面情况会释放锁
下面情况不会释放锁