//测试stop //1.建议线程正常停止---》利用次数,不建议死循环 //2.建议使用标志位--》设置一个标志位 //3.不要使用stop或者destory等过时或者JDK不建议使用的方法 public class TestStop implements Runnable{ //设置一个标志位 private boolean flag = true; @Override public void run() { int i=0; while(flag){ System.out.println("run...Thread"+i++); } } //设置一个公开的方法停止线程,转换标志位 public void stop(){ this.flag=false; } public static void main(String[] args) { TestStop testStop = new TestStop(); new Thread(testStop).start(); for (int i = 0; i < 1000; i++) { System.out.println("main"+i); if(i==900){ //调用stop方法,切换标志位,让线程停止 testStop.stop(); System.out.println("线程该停止了"); } } } }
//模拟网络延时:放大问题的发生性 public class TestSleep implements Runnable { //票数 private int ticketNums = 10; @Override public void run() { while(true){ if(ticketNums<=0){break;} //模拟延时 try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"-->拿到了第"+ticketNums--+"票"); } } public static void main(String[] args) { TestSleep ticket = new TestSleep(); new Thread(ticket,"小明").start(); new Thread(ticket,"老师").start(); new Thread(ticket,"黄牛党").start(); } }
import java.text.SimpleDateFormat; import java.util.Date; public class TestSleep2 { public static void main(String[] args) { //打印当前系统时间 Date startTime = new Date(System.currentTimeMillis());//获取系统当前时间 while(true){ try { Thread.sleep(1000); System.out.println(new SimpleDateFormat("HH:mm:ss").format(startTime)); startTime = new Date(System.currentTimeMillis());//更新当前时间 } catch (InterruptedException e) { e.printStackTrace(); } } // try { // tenDown(); // } catch (InterruptedException e) { // e.printStackTrace(); // } } //模拟倒计时 public static void tenDown() throws InterruptedException { int num=10; while(true){ Thread.sleep(1000); System.out.println(num--); if(num<=0){ break; } } } }
//测试join方法 public class TestJoin implements Runnable { @Override public void run() { for (int i = 0; i < 1000; i++) { System.out.println("线程vip"+i); } } public static void main(String[] args) throws InterruptedException { //启动我们的线程 TestJoin testJoin = new TestJoin(); Thread thread = new Thread(testJoin); thread.start(); //主线程 for (int i = 0; i < 500; i++) { if(i==200){ thread.join();//插队 } System.out.println("main"+i); } } }
//观察测试线程的状态 public class TestState { public static void main(String[] args) throws InterruptedException { Thread thread = new Thread(()->{ for (int i = 0; i < 5; i++) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("/////"); }); //观察状态 Thread.State state = thread.getState(); System.out.println(state);//NEW //观察启动行 thread.start(); state =thread.getState(); System.out.println(state);//run while(state!=Thread.State.TERMINATED){//只要线程不终止,就一直输出状态 Thread.sleep(100); state = thread.getState();//更新线程状态 System.out.println(state);//输出状态 } } }
-
线程的优先级用数字表示,范围从1-10
-
Thread.MIN_PRIORITY = 1;
-
Thread.Max_PRIORITY=10;
-
Thread.NORM_PRIORITY =5;
优先级低只是意味着获得调度的概率低,并不是优先级低就不会被调用,看CPU
//测试线程的优先级 public class TestPriority { public static void main(String[] args) { //主线程默认优先级 System.out.println(Thread.currentThread().getName()+"-->"+Thread.currentThread().getPriority()); MyPriority myPriority = new MyPriority(); Thread t1 = new Thread(myPriority); Thread t2 = new Thread(myPriority); Thread t3 = new Thread(myPriority); Thread t4 = new Thread(myPriority); Thread t5 = new Thread(myPriority); Thread t6 = new Thread(myPriority); //先设置优先级,再启动 t1.start(); t2.setPriority(1); t2.start(); t3.setPriority(4); t3.start(); t4.setPriority(Thread.MAX_PRIORITY); t4.start(); } } class MyPriority implements Runnable{ @Override public void run() { System.out.println(Thread.currentThread().getName()+"-->"+Thread.currentThread().getPriority()); } }
-
线程分为用户线程和守护线程
-
虚拟机必须确保用户线程执行完毕
-
虚拟机不用等待守护线程执行完毕
-
如:后台记录操作日志,监控内存,垃圾回收等待
//测试守护线程 public class TestDaemon { public static void main(String[] args) { God god = new God(); You you = new You(); Thread thread = new Thread(); thread.setDaemon(true);//默认false表示用户线程,正常的线程都是用户线程 thread.start();//守护线程启动 new Thread(you).start();//用户线程启动 } } class God implements Runnable{ @Override public void run() { while(true){ System.out.println("上帝保佑着你"); } } } class You implements Runnable{ @Override public void run() { for (int i = 0; i < 36500; i++) { System.out.println("你一生都开心的活着"); } System.out.println("goodbye world"); } }
不安全案例
//不安全的买票 public class UnsafeBuyTicket { public static void main(String[] args) { BuyTicket station =new BuyTicket(); new Thread(station,"苦逼的我").start(); new Thread(station,"牛逼的你").start(); new Thread(station,"可恶的黄牛党").start(); } } class BuyTicket implements Runnable{ //票 private int ticketNums = 10; boolean flag = true;//外部停止方式 @Override public void run() { //买票 while (flag){ try { buy(); } catch (InterruptedException e) { e.printStackTrace(); } } } private void buy() throws InterruptedException { //判断是否有票 if(ticketNums<=0){ flag=false; return; } //模拟延时 Thread.sleep(100); //买票 System.out.println(Thread.currentThread().getName()+"拿到"+ticketNums--); } }
//不安全的取钱 public class UnsafeBank { public static void main(String[] args) { //账户 Account account = new Account(100,"基金"); Drawing friend = new Drawing(account,100,"friend"); Drawing you = new Drawing(account,50,"你"); you.start(); friend.start(); } } //银行 class Account{ int money;//余额 String name;//卡名 public Account(int money, String name) { this.money = money; this.name = name; } } //银行模拟取款 class Drawing extends Thread{ Account account;//账户 //取了多少钱 int drawingMoney; //现在手里有多少钱 int nowMoney; public Drawing(Account account,int drawingMoney,String name){ super(name); this.account = account; this.drawingMoney = drawingMoney; } //取钱 @Override public void run() { //判断有没有钱 if(account.money-drawingMoney<0){ System.out.println(Thread.currentThread().getName()+"钱不够,取不了"); return; } try {//sleep可以放大问题的发生性 Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } //卡内余额=余额-你取的钱 account.money = account.money-drawingMoney; //你手里的钱 nowMoney = nowMoney+drawingMoney; System.out.println(account.name+"余额为:"+account.money); //Thread.currentThread().getName()=this.getName() System.out.println(this.getName()+"手里的钱:"+nowMoney); } }
//synchronized同步方法 private synchronized void buy() throws InterruptedException { //判断是否有票 if(ticketNums<=0){ flag=false; return; } //模拟延时 Thread.sleep(100); //买票 System.out.println(Thread.currentThread().getName()+"拿到"+ticketNums--); }
//取钱 // synchronized默认锁的是this @Override public void run() { //锁的对象就是变化的量,即增删改 synchronized (account){ //判断有没有钱 if(account.money-drawingMoney<0){ System.out.println(Thread.currentThread().getName()+"钱不够,取不了"); return; } try {//sleep可以放大问题的发生性 Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } //卡内余额=余额-你取的钱 account.money = account.money-drawingMoney; //你手里的钱 nowMoney = nowMoney+drawingMoney; System.out.println(account.name+"余额为:"+account.money); //Thread.currentThread().getName()=this.getName() System.out.println(this.getName()+"手里的钱:"+nowMoney); } }
-
Lock是显示锁(手动开启和关闭锁) synchronized是隐式锁,出了作用域自动释放
-
Lock只有代码块锁,synchronized有代码块锁和方法锁
-
使用lock锁,JVM将花费较少的时间来调度线程,性能更好。并且具有更好的扩展性(提供更多的子类)
-
优先使用顺序lock>同步代码块(已经进入了方法体,分配了相应的资源)>同步方法(在方法体之外)
import java.util.concurrent.locks.ReentrantLock; //测试lock锁 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{ int ticketNums = 10; //定义lock锁 private final ReentrantLock lock = new ReentrantLock(); @Override public void run() { while(true){ try{ lock.lock();//加锁 if(ticketNums>0){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(ticketNums--); }else { break; } }finally { //解锁 lock.unlock(); } } } }
//测试:生产者消费者模型,利用缓冲区解决:管程法 public class TestPC { public static void main(String[] args) { SynContainer container = new SynContainer(); new Producer(container).start(); new Consumer(container).start(); } } //生产者 class Producer extends Thread{ SynContainer container; public Producer(SynContainer container) { this.container = container; } //生产 @Override public void run() { for (int i = 0; i < 100; i++) { container.push(new Product(i)); System.out.println("生产了"+i+"个产品"); } } } //消费者 class Consumer extends Thread{ SynContainer container; public Consumer(SynContainer container) { this.container = container; } @Override public void run() { for (int i = 0; i < 100; i++) { System.out.println("消费了"+container.pop().id+"个产品"); } } } //产品 class Product extends Thread{ int id;//产品编号 public Product(int id){ this.id =id; } } //缓冲区 class SynContainer{ //需要一个容器大小 Product[] products = new Product[10]; //容器计数器 int count = 0; //生产者放入产品 public synchronized void push(Product product){ //如果容器满了,就需要等待消费 if(count==products.length){ //通知消费者消费,生产等待 try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } //如果没有满,就需要丢入产品 products[count] = product; count++; //可以通知消费者消费了 this.notifyAll(); } //消费者消费产品 public synchronized Product pop(){ //判断能否消费 if(count==0){ //等待生产者生产,消费者等待 try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } //如果可以消费 count--; Product product = products[count]; //消费完,通知生产者生产 this.notifyAll(); return product; } }
//测试生产者消费者问题2:信号灯法,标志位解决 public class TestPC2 { public static void main(String[] args) { TV tv = new TV(); new Player(tv).start(); new Watcher(tv).start(); } } //生产者-演员 class Player extends Thread{ TV tv; public Player(TV tv){ this.tv = tv; } @Override public void run() { for (int i = 0; i < 20; i++) { if(i%2==0){ this.tv.play("音乐银行播放中"); }else{ this.tv.play("电影播放中"); } } } } //消费者-观众 class Watcher extends Thread{ TV tv; public Watcher(TV tv) { this.tv = tv; } @Override public void run() { for (int i = 0; i < 20; i++) { tv.watch(); } } } //产品-节目 class TV{ //演员表演,观众等待 //观众观看,演员等待 String voice;//表演的节目 boolean flag = true; //表演 public synchronized void play(String voice){ if(!flag){ try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } //通知观众观看 this.notifyAll();//通知唤醒 this.voice = voice; this.flag = !this.flag;//标志位切换 } //观看 public synchronized void watch(){ if(flag){ try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("观看了:"+voice); //通知演员表演 this.notifyAll(); this.flag = !this.flag; } }
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; //测试线程池 public class TestPool { public static void main(String[] args) { //创建服务,创建线程池 //newFixedThreadPool 参数为线程池大小 ExecutorService service = Executors.newFixedThreadPool(10); //执行 service.execute(new MyThread()); service.execute(new MyThread()); service.execute(new MyThread()); service.execute(new MyThread()); //关闭连接 service.shutdown(); } } class MyThread implements Runnable{ @Override public void run() { System.out.println(Thread.currentThread().getName()); } }