一个进程包含多个线程,通过时间片的轮转
一 、线程的创建 Runnable是Java中用以实现线程的接口,包含了run方法,可以通过以下两个方法实现这个接口
1、继承Thread类或者其子类
2、自己创建一个实现类实现Runnable 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public class Runnable1 implements Runnable { @Override public void run () { for (int i = 0 ; i < 20 ; i++) { System.out.println("我" + i); } } public static void main (String[] args) { Runnable1 r = new Runnable1(); new Thread(r).start(); for (int i = 0 ; i < 1000 ; i++) { System.out.println("爱你" + i); } } }
3、 还有一种暂时可能用不到 Callable接口 4 补充 函数式接口
只有唯一一个抽象方法的接口
可以通过LAMBDA表达式来创建该接口的对象
函数式接口的实现有很多方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 public class TestLambda1 { static class Like2 implements ILike { @Override public void lambda () { System. out.println("i like lambda2" ) ; } public static void main (String[] args) { ILike1 like = new Like () ; like. lambda() ; like = new Like2 () ; like. lambda () ; class Like3 implements ILike { @Override public void lambda () { System. out.println("i like lambda3" ) ; } } like = new Like3() ; like. lambda () ; . like = new ILike () { @Override public void lambda () { System. out.println("i like lambda4" ) ; }; like. lambda () ; } like = ()->{ System. out.println("i like lambda5" ) ; }; 1 ike. lambda () ; } interface ILike { void lambda () ; } class Like implements ILike1 { @Override public void lambda () { System.out.println("i like lambda" ) ; } }
二、线程的运行
1 停止
不推荐使用JDK提供的stop() destroy()方法,已废弃
推荐线程自己停止下来 ,建议使用一个标志位进行终止变量,当flag=false,则终止线程运行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 public class TestStop implements Runnable { private boolean flag = true ; @Override public void run () { int i = 0 ; while (flag) System.out.println("Thread is running" + i++); } public void stop () { this .flag = false ; } public static void main (String[] args) { TestStop t = new TestStop(); new Thread(t).start(); for (int i = 0 ; i <1000 ; i++) { System.out.println("main is running" + i); if (i == 900 ) t.stop(); System.out.println("线程停止了" ); } } }
2 休眠
sleep (时间)指定当前线程阻塞的毫秒数;
sleep存在异常 InterruptedException,
sleep时间达到后线程进入就绪状态;
sleep可以模拟网络延时(放大问题发生性),倒计时等。
每一个对象都有一个锁,sleep不会释放锁;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public class TestSleep2 {public static void main (String[] args) { try { tenDown() ; } catch (InterruptedException e) { e. printStackTrace() ; } } public static void tenDown () throws Inter ruptedException { int num=10 ; while (true ){ Thread.sleep( millis: 1000 ) ; System.out.println(num--); if (num<=0 ) break ; } } }
3 礼让
礼让线程,让当前正在执行的线程暂停,但不阻塞
将线程从运行状态转为就绪状态 让cpu重新调度
==礼让不一定成功!==看CPU心情
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ) ) public class TestYield {public static void main (String[] args) {MyYield myYield = new MyYield(); new Thread (myYield, name: "a" ) .start();new Thread (myYield, name: "b" ) .start() ;} } class MyYield implements Runnable {@Override public void run () {System.out.println(Thread . currentThread().getName() +"线程开始执行" ); Thread.yield(); System. out .println(Thread . currentThread() . getName()+"线程停止执行" ); } }
4 强制执行 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 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); } } } }
5 线程状态 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 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); thread.start(); state = thread.getState(); System.out.println(state); while (state != Thread.State.TERMINATED) { Thread.sleep(100 ); state = thread.getState(); System.out.println(state); } } }
6 线程优先级
Java提供一个线程调度器来监控程 序中启动后进入就绪状态的所有线程,线程调度 器按照优先级决定应该调度哪个线程来执行。线程的优先级用数字表示,范围从1~10.
Thread.MIN PRIORITY = 1; Thread.MAX_ PRIORITY = 10; Thread.NORM PRIORITY = 5;
使用以下方式改变或获取优先级. getPriority() . setPriority(int xx)
但是优先级只是影响调度概率,不是一定
7 守护线程 设置为守护线程后,该线程会随着用户线程结束
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 public class TestDaemon { public static void main (String[] args) { God god = new God() ; You you = new You() ; Thread thread = new Thread(god) ; thread . setDaemon(true ); 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 (inti=0 ;i<36500 ;i++){ System. out . println("你一生都开心的活着" ) ; } System. out .println("-====goodbye! world!======" ); }
三、线程的同步 1 锁
synchronized方法控制对“对象”的访问,每个对象对应一 -把锁 ,每个synchronized方法都必须获得调用该方法的对象的锁才能执行,否则线程会阻塞,方法一旦执行,就独占该锁,直到该方法返回才释放锁,后面被阻塞的线程才能获得这个锁,继续执行
不能直接锁run,如果run调用了其他方法,可以锁那个调用的方法,如果是直接在run里面写的方法,要用synchronczed块锁
synchronized (){}
2 死锁 产生死锁的四个必要条件:
互斥条件:一个资源每次只能被一一个进程使用。
请求与保持条件: 一个进程因请求资源而阻塞时,对已获得的资源保持不放。
不剥夺条件 :进程已获得的资源,在末使用完之前,不能强行剥夺。
循环等待条件:若干进程之间形成- -种头尾相接的循环等待资源关系。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 public class DeadLock { public static void main (String[] args) { Makeup g1 = new Makeup(0 , "灰姑凉" ); Makeup g2 = new Makeup(1 , "白雪公主" ); g1.start(); g2.start(); } } class Lipstick { } class Mirror { } class Makeup extends Thread { static Lipstick Lipstick = new Lipstick(); static Mirror mirror = new Mirror(); int choice; String girlNmae; Makeup(int choice, String girlNmae) { this .choice = choice; this .girlNmae = girlNmae; } @Override public void run () { try { makeup(); } catch (InterruptedException e) { e.printStackTrace(); } } private void makeup () throws InterruptedException { if (choice == 0 ) { synchronized (Lipstick) { System.out.println(this .girlNmae + "获得口红的锁" ); Thread.sleep(1000 ); } synchronized (mirror) { System.out.println(this .girlNmae + "获得镜子的锁" ); } } else { synchronized (mirror) { System.out.println(this .girlNmae + "获得镜子的锁" ); Thread.sleep(2000 ); } synchronized (Lipstick) { System.out.println(this .girlNmae + "获得口红的锁" ); } } } }
3 lock锁 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 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 ; private final ReentrantLock lock = new ReentrantLock(){ @override public void run () { while (true ) { try { lock. lock(); if (ticketNums>0 ) { try { Thread . sleep( millis: 1000 ) ; } catch (Inter ruptedException e) { e. printStackTrace() ; System .out . pr intln (ticketNums--) ; }else break ; }finally { Lock . unlock() ; } } }
四、线程协作