用两个经典java笔试题来理解。
一。创建两个线程,分别打印100以内的偶数和奇数(不包含线程安全)
1 //创建两个线程,分别打印100以内的偶数和奇数 2 //判断多个线程是否存在线程的安全问题:是否存在共享数据 3 public class TestThread { 4 public static void main(String[] args) { 5 //创建了继承Thread类的匿名类的匿名对象 6 new Thread("线程1"){ 7 public void run(){ 8 for(int i = 1;i <= 100;i++){ 9 if(i % 2 == 0){ 10 System.out.println(Thread.currentThread().getName() + ":" + i); 11 } 12 } 13 } 14 }.start(); 15 16 new Thread("线程2"){ 17 public void run(){ 18 for(int i = 1;i <= 100;i++){ 19 if(i % 2 != 0){ 20 System.out.println(Thread.currentThread().getName() + ":" + i); 21 } 22 } 23 } 24 }.start(); 25 } 26 }
二。生产者(Productor)将产品交给店员(Clerk),而消费者(Customer)从店员处取走产品,店员一次只能持有固定数量的产品(比如:20),如果生产者试图生产更多的产品,店员会叫生产者停一下,如果店中有空位放产品了再通知生产者继续生产;如果店中没有产品了,店员会告诉消费者等一下,如果店中有产品了再通知消费者来取走产品。(线程安全)
1 /* 2 * 经典例题:生产者/消费者问题 3 生产者(Productor)将产品交给店员(Clerk),而消费者(Customer)从店员处取 4 走产品,店员一次只能持有固定数量的产品(比如:20),如果生产者试图生产更多的产品, 5 店员会叫生产者停一下,如果店中有空位放产品了再通知生产者继续生产;如果店中没有 6 产品了,店员会告诉消费者等一下,如果店中有产品了再通知消费者来取走产品。 7 1.是否存在多线程?是! 8 2.多个线程分别是什么呢?生产者 消费者 9 3.是否存在共享数据?是 10 4.共享数据是:产品。需要考虑线程的同步,用来解决线程的安全问题 11 5.是否存在线程的通信?是 12 */ 13 14 class Clerk{//店员 15 int product; 16 17 public synchronized void consumeProduct(){//消费产品 18 if(product <= 0){ 19 try { 20 wait(); 21 } catch (InterruptedException e) { 22 // TODO Auto-generated catch block 23 e.printStackTrace(); 24 } 25 }else{ 26 System.out.println(Thread.currentThread().getName() + ":消费了第" + product + "个产品"); 27 product--; 28 notifyAll(); 29 } 30 } 31 32 public synchronized void addProduct(){//生产产品 33 if(product >= 20){ 34 try { 35 wait(); 36 } catch (InterruptedException e) { 37 // TODO Auto-generated catch block 38 e.printStackTrace(); 39 } 40 }else{ 41 product++; 42 System.out.println(Thread.currentThread().getName() + ":生产了第" + product + "个产品"); 43 notifyAll(); 44 } 45 } 46 } 47 48 class Comsumer implements Runnable{//消费者 49 Clerk clerk; 50 public Comsumer(Clerk clerk){ 51 this.clerk = clerk; 52 } 53 @Override 54 public void run() { 55 System.out.println("消费者开始消费产品"); 56 while(true){ 57 try { 58 Thread.sleep((int)(Math.random() * 1000)); 59 } catch (InterruptedException e) { 60 // TODO Auto-generated catch block 61 e.printStackTrace(); 62 } 63 clerk.consumeProduct(); 64 65 } 66 } 67 } 68 69 class Productor implements Runnable{//生产者 70 Clerk clerk; 71 72 public Productor(Clerk clerk){ 73 this.clerk = clerk; 74 } 75 76 @Override 77 public void run() { 78 System.out.println("生产者开始生产产品"); 79 while(true){ 80 try { 81 Thread.sleep((int)(Math.random() * 1000)); 82 } catch (InterruptedException e) { 83 // TODO Auto-generated catch block 84 e.printStackTrace(); 85 } 86 clerk.addProduct(); 87 } 88 } 89 } 90 91 92 public class TestProduct { 93 public static void main(String[] args) { 94 Clerk clerk = new Clerk(); 95 96 Productor p1 = new Productor(clerk); 97 Thread t1 = new Thread(p1);//创建了一个生产者 98 Thread t2 = new Thread(p1); 99 100 Comsumer c1 = new Comsumer(clerk); 101 Thread tt1 = new Thread(c1);//创建了一个消费者 102 103 t1.start(); 104 t2.start(); 105 tt1.start(); 106 107 } 108 }