多线程案例

一、生产者消费者案例

1.使用synchronized关键字实现

 1 public class TestProductorAndConsumer {
 2         public static void main(String[] args) {
 3             Clerk clerk = new Clerk();
 4             Productor pro = new Productor(clerk);
 5             Consumer cus = new Consumer(clerk);
 6         
 7             new Thread(pro, "生产者 A").start();
 8             new Thread(cus, "消费者 B").start();
 9             new Thread(pro, "生产者 C").start();
10             new Thread(cus, "消费者 D").start();
11     }    
12 }
13 //店员
14 class Clerk{
15     private int product = 0;
16     //进货
17     public synchronized void get(){    //循环次数:0
18         while(product >= 1){    
19             System.out.println("产品已满!");
20             try {
21                 this.wait();    //为了避免虚假唤醒问题,wait应该总是使用在循环中
22             } catch (InterruptedException e) {
23             }    
24         }
25         System.out.println(Thread.currentThread().getName() + " : " + ++product);
26         this.notifyAll();
27     }
28     //卖货
29     public synchronized void sale(){    //product = 0; 循环次数:0
30         while(product <= 0){
31             System.out.println("缺货!");
32             try {
33                 this.wait();
34             } catch (InterruptedException e) {
35             }
36         }
37         System.out.println(Thread.currentThread().getName() + " : " + --product);
38         this.notifyAll();
39     }
40 }
41 //生产者
42 class Productor implements Runnable{
43     private Clerk clerk;
44     public Productor(Clerk clerk) {
45         this.clerk = clerk;
46     }
47     public void run() {
48         for (int i = 0; i < 20; i++) {
49             try {
50                 Thread.sleep(200);
51             } catch (InterruptedException e) {
52             }
53             clerk.get();
54         }
55     }
56 }
57 //消费者
58 class Consumer implements Runnable{
59     private Clerk clerk;
60     public Consumer(Clerk clerk) {
61         this.clerk = clerk;
62     }
63     public void run() {
64         for (int i = 0; i < 20; i++) {
65             clerk.sale();
66         }
67     }
68 }

2.使用Lock同步锁和Condition类实现

 1 public class TestProductorAndConsumerForLock {
 2     public static void main(String[] args) {
 3         Clerk clerk = new Clerk();
 4         Productor pro = new Productor(clerk);
 5         Consumer con = new Consumer(clerk);
 6 
 7         new Thread(pro, "生产者 A").start();
 8         new Thread(con, "消费者 B").start();
 9 //        new Thread(pro, "生产者 C").start();
10 //        new Thread(con, "消费者 D").start();
11     }
12 }
13 class Clerk {
14     private int product = 0;
15     private Lock lock = new ReentrantLock();
16     private Condition condition = lock.newCondition();
17     // 进货
18     public void get() {
19         lock.lock();
20         try {
21             if (product >= 1) { // 为了避免虚假唤醒,应该总是使用在循环中。
22                 System.out.println("产品已满!");
23                 try {
24                     condition.await();
25                 } catch (InterruptedException e) {
26                 }
27             }
28             System.out.println(Thread.currentThread().getName() + " : "+ ++product);
29             condition.signalAll();
30         } finally {
31             lock.unlock();
32         }
33     }
34     // 卖货
35     public void sale() {
36         lock.lock();
37         try {
38             if (product <= 0) {
39                 System.out.println("缺货!");
40                 try {
41                     condition.await();
42                 } catch (InterruptedException e) {
43                 }
44             }
45             System.out.println(Thread.currentThread().getName() + " : "+ --product);
46             condition.signalAll();
47         } finally {
48             lock.unlock();
49         }
50     }
51 }
52 
53 // 生产者
54 class Productor implements Runnable {
55     private Clerk clerk;
56     public Productor(Clerk clerk) {
57         this.clerk = clerk;
58     }
59     public void run() {
60         for (int i = 0; i < 20; i++) {
61             try {
62                 Thread.sleep(200);
63             } catch (InterruptedException e) {
64                 e.printStackTrace();
65             }
66             clerk.get();
67         }
68     }
69 }
70 
71 // 消费者
72 class Consumer implements Runnable {
73     private Clerk clerk;
74     public Consumer(Clerk clerk) {
75         this.clerk = clerk;
76     }
77     public void run() {
78         for (int i = 0; i < 20; i++) {
79             clerk.sale();
80         }
81     }
82 }

 

二、线程按序交替

  编写一个程序,开启3个线程,这三个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,要求输出的结果必须按顺序显示。如:ABCABC......依次递归。

 1 public class TestABCAlternate {
 2     public static void main(String[] args) {
 3         AlternateDemo ad = new AlternateDemo();
 4         new Thread(new Runnable() {
 5             public void run() {
 6                 for (int i = 1; i <= 10; i++) {
 7                     ad.loopA(i);
 8                 }    
 9             }
10         }, "A").start();
11         new Thread(new Runnable() {
12             public void run() {    
13                 for (int i = 1; i <= 10; i++) {
14                     ad.loopB(i);
15                 }    
16             }
17         }, "B").start();
18         new Thread(new Runnable() {
19             public void run() {
20                 for (int i = 1; i <= 10; i++) {
21                     ad.loopC(i);
22                     System.out.println("-----------------------------------");
23                 }    
24             }
25         }, "C").start();
26     }
27 }
28 
29 class AlternateDemo{
30     private int number = 1; //当前正在执行线程的标记
31     private Lock lock = new ReentrantLock();
32     private Condition condition1 = lock.newCondition();
33     private Condition condition2 = lock.newCondition();
34     private Condition condition3 = lock.newCondition();
35     
36     public void loopA(int totalLoop){    //totalLoop : 循环第几轮
37         lock.lock();
38         try {
39             if(number != 1){    //1. 判断
40                 condition1.await();
41             }
42             //2. 打印
43             for (int i = 1; i <= 1; i++) {
44                 System.out.println(Thread.currentThread().getName() + "\t" + i + "\t" + totalLoop);
45             }
46             //3. 唤醒
47             number = 2;
48             condition2.signal();
49         } catch (Exception e) {
50             e.printStackTrace();
51         } finally {
52             lock.unlock();
53         }
54     }
55     public void loopB(int totalLoop){
56         lock.lock();
57         try {
58             if(number != 2){    //1. 判断
59                 condition2.await();
60             }
61             //2. 打印
62             for (int i = 1; i <= 1; i++) {
63                 System.out.println(Thread.currentThread().getName() + "\t" + i + "\t" + totalLoop);
64             }
65             //3. 唤醒
66             number = 3;
67             condition3.signal();
68         } catch (Exception e) {
69             e.printStackTrace();
70         } finally {
71             lock.unlock();
72         }
73     }
74     public void loopC(int totalLoop){
75         lock.lock();
76         try {
77             if(number != 3){    //1. 判断
78                 condition3.await();
79             }    
80             //2. 打印
81             for (int i = 1; i <= 1; i++) {
82                 System.out.println(Thread.currentThread().getName() + "\t" + i + "\t" + totalLoop);
83             }
84             //3. 唤醒
85             number = 1;
86             condition1.signal();
87         } catch (Exception e) {
88             e.printStackTrace();
89         } finally {
90             lock.unlock();
91         }
92     }
93 }
上一篇:kvm虚拟磁盘设备全过程


下一篇:VIRTIO & VHOST