多线程的实现方式
通过实现 Runnable 接口
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 package com.ruanyuan;public class TestThread { public static void main (String[] args) { RunnableDemo demo = new RunnableDemo(); new Thread(demo).start(); for (int i = 0 ; i < 1000 ; i++) { System.out.println("主线程" ); } } } class RunnableDemo implements Runnable { public void run () { for (int i = 0 ; i < 1000 ; i++) { System.out.println("子线程--" +Thread.currentThread().getName()); } } }
推荐使用Runnable对象,因为Java单继承的局限性
通过继承 Thread 类本身
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 package com.ruanyuan;public class TestThread { public static void main (String[] args) { ThreadRDemo demo = new ThreadRDemo(); demo.start(); for (int i = 0 ; i < 1000 ; i++) { System.out.println("主线程" ); } } } class ThreadRDemo extends Thread { public void run () { for (int i = 0 ; i < 1000 ; i++) { System.out.println("子线程--" +Thread.currentThread().getName()); } } }
线程同步
线程安全案例一
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 package com.ruanyuan;import java.util.ArrayList;import java.util.List;public class TestThread { public static void main (String[] args) { List<String> list = new ArrayList<>(); for (int i = 0 ; i < 10000 ; i++) { new Thread(() -> { list.add(Thread.currentThread().getName()); }).start(); } try { Thread.sleep(3000 ); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(list.size()); } }
并发太快,对集合的操作有的重复在了一个位置。
同步代码块
线程安全案例二
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 package com.ruanyuan;public class TestThread { public static void main (String[] args) { BuyTicket buyTicket = new BuyTicket(); new Thread(buyTicket, "张三" ).start(); new Thread(buyTicket, "李四" ).start(); new Thread(buyTicket, "王五" ).start(); } } class BuyTicket implements Runnable { private int ticketNums = 10 ; boolean flag = true ; @Override public void run () { while (flag) { try { buy(); } catch (Exception e) { e.printStackTrace(); } } } private void buy () { if (ticketNums <= 0 ) { flag = false ; return ; } try { Thread.sleep(1 ); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "拿到" + ticketNums--); } }
同步方法
死锁
案例
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 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 package com.ruanyuan;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 girlName; public MakeUp (int choice, String girlName) { this .choice = choice; this .girlName = girlName; } @Override public void run () { makeup(); } private void makeup () { if (choice == 0 ) { synchronized (lipStick) { System.out.println(this .girlName+"获得口红的锁" ); try { Thread.sleep(1000 ); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (mirror) { System.out.println(this .girlName+"获得镜子的锁" ); } } } else { synchronized (mirror) { System.out.println(this .girlName+"获得镜子的锁" ); try { Thread.sleep(2000 ); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (lipStick) { System.out.println(this .girlName+"获得口红的锁" ); } } } } }
解决