Java 多线程之间的通信
一个线程送水,一个线程出水:多个线程操作同一个资源,但操作的动作不同。两个线程操作同一资源,但操作的动作不一样。两个方法

package cn.itcast.day5.thread; //一进一出 public class 线程通信 { public static void main(String[] args) { Resouce resouce = new Resouce(); Input input = new Input(resouce); OutPut outPut = new OutPut(resouce); Thread thread1 = new Thread(input); Thread thread2 = new Thread(outPut); thread1.start(); thread2.start(); } } class Resouce { public String name; public String sex; } class Input implements Runnable { Resouce resouce; Input(Resouce resouce) { this.resouce = resouce; } @Override public void run() { int x = 1; while (true) { synchronized (Input.class)//两个线程的锁只要是一个object 在内存中的字节码 { if (x == 0) { resouce.name = "peter.peng"; resouce.sex = "boy"; } else { resouce.name = "彭运松"; resouce.sex = "男"; } x = (x + 1) % 2; } } } } class OutPut implements Runnable { Resouce resouce; OutPut(Resouce resouce) { this.resouce = resouce; } @Override public void run() { while (true) { synchronized (Input.class) //两个线程的锁只要是一个object 在内存中的字节码 { System.out.println(Thread.currentThread() + "-----:" + resouce.name + ":" + resouce.sex); } } } }
如果要达到一进一去,交替出现而不是从上一案例一样,则得用到 wait() notify() notityAll(),理解这几个意义

1 package cn.itcast.day5.thread; 2 3 //一进一出 4 public class 线程通信 5 { 6 public static void main(String[] args) 7 { 8 Resouce resouce = new Resouce(); 9 Input input = new Input(resouce); 10 OutPut outPut = new OutPut(resouce); 11 12 Thread thread1 = new Thread(input); 13 Thread thread2 = new Thread(outPut); 14 15 thread1.start(); 16 thread2.start(); 17 } 18 } 19 20 class Resouce 21 { 22 public String name; 23 public String sex; 24 boolean flag=false; 25 } 26 27 class Input implements Runnable 28 { 29 Resouce resouce; 30 31 Input(Resouce resouce) 32 { 33 this.resouce = resouce; 34 } 35 36 @Override 37 public void run() 38 { 39 int x = 0; 40 while (true) 41 { 42 synchronized (resouce)// 两个线程的锁只要是一个object 在内存中的字节码 43 { 44 if(resouce.flag) 45 try 46 { 47 wait(); 48 //由于第一次flag=false 所以线程1不会等待,就会执行x==0,赋一次值,赋值完后,flag=true,这时线程1 49 //就会等待,同是叫醒线程2. 50 //由于flag=true 则线程2不会等待,就会执行输出语句,输出完后,flag=false,这时线程2就会等待,同时叫醒线程1 51 //这时就会执行else语句给resource第二次赋值,赋完值后x=(x+1)%2,这里x=0,同时flag=true,线程1又等待。同时 52 //第二次叫醒线程2 ............. 53 } 54 catch (Exception e) 55 { 56 } 57 if (x == 0) 58 { 59 resouce.name = "peter.peng"; 60 resouce.sex = "boy"; 61 } else 62 { 63 resouce.name = "彭运松"; 64 resouce.sex = "男"; 65 } 66 x = (x + 1) % 2; 67 resouce.flag = true; 68 resouce.notify();// 叫醒线程2 69 } 70 } 71 } 72 73 } 74 75 class OutPut implements Runnable 76 { 77 Resouce resouce; 78 79 OutPut(Resouce resouce) 80 { 81 this.resouce = resouce; 82 } 83 84 @Override 85 public void run() 86 { 87 while (true) 88 { 89 synchronized (resouce) // 两个线程的锁只要是一个object 在内存中的字节码 90 { 91 if (!resouce.flag) 92 try 93 { 94 resouce.wait(); 95 } 96 catch (Exception e) 97 { 98 99 } 100 System.out.println(resouce.name + ":" + resouce.sex); 101 resouce.flag = false; 102 resouce.notify();//叫醒线程1 103 } 104 } 105 } 106 }
对等待线程的优化(上一程序) 对Resurce进行封装,并把set get 方法进行同步。
生者消费者的例子

1 package net.nw.entites; 2 3 public class ThreadDemo_Product_Customer { 4 5 public static void main(String[] args) { 6 7 Resource resource = new Resource(); 8 Product product = new Product(resource); 9 Customer customer = new Customer(resource); 10 11 Thread t1 = new Thread(product); 12 Thread t2 = new Thread(customer); 13 Thread t3 = new Thread(product); 14 Thread t4 = new Thread(customer); 15 16 t1.start(); 17 t2.start(); 18 t3.start(); 19 t4.start(); 20 } 21 } 22 23 class Resource { 24 public String name; 25 public boolean flag; 26 public int count = 0; 27 28 public synchronized void Set(String name) { 29 while (true) { 30 while(flag) { 31 try { 32 wait(); 33 } catch (Exception e) { 34 e.printStackTrace(); 35 } 36 } 37 this.name = name + count++; 38 System.out.println(Thread.currentThread().getName() + "-P:" 39 + this.name); 40 flag = true; 41 notifyAll(); 42 } 43 } 44 45 public synchronized void getOut() { 46 while (true) { 47 while (!flag) { 48 try { 49 wait(); 50 } catch (Exception e) { 51 e.printStackTrace(); 52 } 53 } 54 System.out.println(Thread.currentThread().getName() + "-C:" 55 + this.name); 56 flag = false; 57 notifyAll(); 58 } 59 } 60 } 61 62 class Product implements Runnable { 63 Resource resource; 64 65 Product(Resource resource) { 66 this.resource = resource; 67 } 68 69 @Override 70 public void run() { 71 resource.Set("pc"); 72 } 73 } 74 75 class Customer implements Runnable { 76 Resource resource; 77 78 Customer(Resource resource) { 79 this.resource = resource; 80 } 81 82 @Override 83 public void run() { 84 resource.getOut(); 85 } 86 87 }
JdK1.5 新特性的多线程操作

1 package net.nw.entites; 2 3 import java.util.concurrent.locks.Condition; 4 import java.util.concurrent.locks.Lock; 5 import java.util.concurrent.locks.ReentrantLock; 6 7 public class ThreadDemo_Product_Customer { 8 9 public static void main(String[] args) { 10 11 Resource resource = new Resource(); 12 Product product = new Product(resource); 13 Customer customer = new Customer(resource); 14 15 Thread t1 = new Thread(product); 16 Thread t2 = new Thread(customer); 17 Thread t3 = new Thread(product); 18 Thread t4 = new Thread(customer); 19 20 t1.start(); 21 t2.start(); 22 t3.start(); 23 t4.start(); 24 } 25 } 26 27 class Resource { 28 public String name; 29 public boolean flag; 30 public int count = 0; 31 32 final Lock lock = new ReentrantLock(); 33 final Condition notFull = lock.newCondition(); 34 final Condition notEmpty = lock.newCondition(); 35 36 public void Set(String name) { 37 lock.lock(); 38 try { 39 while (true) { 40 while (flag) { 41 try { 42 notFull.await(); 43 } catch (Exception e) { 44 e.printStackTrace(); 45 } 46 } 47 this.name = name + count++; 48 System.out.println(Thread.currentThread().getName() + "-P:" 49 + this.name); 50 flag = true; 51 notEmpty.signal(); 52 } 53 } finally { 54 lock.unlock(); 55 } 56 } 57 58 public void getOut() { 59 lock.lock(); 60 try { 61 while (true) { 62 while (!flag) { 63 try { 64 notEmpty.await(); 65 } catch (Exception e) { 66 e.printStackTrace(); 67 } 68 } 69 System.out.println(Thread.currentThread().getName() + "-C:" 70 + this.name); 71 flag = false; 72 notFull.signal(); 73 } 74 } finally { 75 lock.unlock(); 76 } 77 } 78 } 79 80 class Product implements Runnable { 81 Resource resource; 82 83 Product(Resource resource) { 84 this.resource = resource; 85 } 86 87 @Override 88 public void run() { 89 resource.Set("pc"); 90 } 91 } 92 93 class Customer implements Runnable { 94 Resource resource; 95 96 Customer(Resource resource) { 97 this.resource = resource; 98 } 99 100 @Override 101 public void run() { 102 resource.getOut(); 103 } 104 105 }
说明:Lock提供更为优秀的方法来替换synchronized lock.lock lock.unlock(放在finally)
await single singleall 分别对应 wait notify notifyAll ,但JDK1.5后提供了codition,可以为生产消费指这不同的codition,这样两个线程或是两个以上线程就可以分开出来控制
如果是同一个codition singleAll时就会呼醒其它的线程同时也可以是同类的线程,达不到控制的效果。
线程的中断:其实只要控制住run方法的循环条件就可以了,但有一种情况下await()时就没有办法做了,因为根本就不会执行循环体的语句,这时要用到interruput,使线程势抛出一个异常InterruptedException
,然后在验证循环体的条件。

1 package net.nw.entites; 2 3 import java.util.concurrent.locks.Condition; 4 import java.util.concurrent.locks.Lock; 5 import java.util.concurrent.locks.ReentrantLock; 6 7 public class ThreadDemo_Product_Customer { 8 9 public static void main(String[] args) { 10 11 Resource resource = new Resource(); 12 Product product = new Product(resource); 13 Customer customer = new Customer(resource); 14 15 Thread t1 = new Thread(product); 16 Thread t2 = new Thread(customer); 17 Thread t3 = new Thread(product); 18 Thread t4 = new Thread(customer); 19 t1.start(); 20 t2.start(); 21 22 // t3.start(); 23 // t4.start(); 24 } 25 } 26 27 class Resource { 28 public String name; 29 public boolean flag; 30 public boolean conditionFlag = true; 31 public int count = 0; 32 33 final Lock lock = new ReentrantLock(); 34 final Condition notFull = lock.newCondition(); 35 final Condition notEmpty = lock.newCondition(); 36 37 public void Set(String name) { 38 39 lock.lock(); 40 try { 41 while (conditionFlag) { 42 while (flag) { 43 try { 44 notFull.await(); 45 Thread.currentThread().interrupt();//把当前的线程中断了。 46 } catch (InterruptedException e) { 47 conditionFlag = false; 48 } 49 } 50 this.name = name + count++; 51 System.out.println(Thread.currentThread().getName() + "-P:" 52 + this.name); 53 flag = true; 54 notEmpty.signal(); 55 } 56 } finally { 57 lock.unlock(); 58 if (Thread.interrupted()) { 59 System.out.println(Thread.currentThread().getName() 60 + ":线程中断了。。。。。。。。。。。"); 61 } 62 } 63 } 64 65 public void getOut() { 66 67 lock.lock(); 68 try { 69 while (conditionFlag) { 70 while (!flag) { 71 try { 72 notEmpty.await(); 73 Thread.currentThread().interrupt();//把当前的线程中断了。 74 } catch (InterruptedException e) { 75 conditionFlag = false; 76 } 77 } 78 System.out.println(Thread.currentThread().getName() + "-C:" 79 + this.name); 80 flag = false; 81 notFull.signal(); 82 } 83 } finally { 84 lock.unlock(); 85 if (Thread.interrupted()) { 86 System.out.println(Thread.currentThread().getName() 87 + ":线程中断了。。。。。。。。。。。"); 88 } 89 } 90 } 91 } 92 93 class Product implements Runnable { 94 Resource resource; 95 96 Product(Resource resource) { 97 this.resource = resource; 98 } 99 100 @Override 101 public void run() { 102 resource.Set("pc"); 103 } 104 } 105 106 class Customer implements Runnable { 107 Resource resource; 108 109 Customer(Resource resource) { 110 this.resource = resource; 111 } 112 113 @Override 114 public void run() { 115 resource.getOut(); 116 } 117 118 }
线程的join setDaemon yield

1 package cn.itcast.day5.thread; 2 3 class Demo1 implements Runnable 4 { 5 private int count = 100; 6 7 @Override 8 public void run() 9 { 10 while (count > 0) 11 { 12 System.out.println(Thread.currentThread().getName() + ":" + "------peter.peng" + count--); 13 Thread.yield(); 14 } 15 } 16 } 17 18 public class ThreadJionYield 19 { 20 public static void main(String[] args) throws InterruptedException 21 { 22 // SetDaemon();//设为后台线程 23 // ThreadJoin();//join可以用来时加入线程,遇到一个线程的Join主线程冻结,其它的不变,只到Join这个线程结束,主线程再执行。 24 // SetPriority();//设置线程的优势级 25 Thread thread1 = new Thread(new Demo1());//yield让当前线程停止执行另一个线程。 26 Thread thread2 = new Thread(new Demo1()); 27 28 thread1.start(); 29 thread2.start(); 30 } 31 32 private static void SetPriority() 33 { 34 Thread thread1 = new Thread(new Runnable() 35 { 36 int count = 100; 37 38 public void run() 39 { 40 while (count > 0) 41 { 42 System.out.println(Thread.currentThread().toString() + "------peter.peng" + count--); 43 } 44 } 45 }); 46 47 Thread thread2 = new Thread(new Runnable() 48 { 49 int count = 100; 50 51 public void run() 52 { 53 while (count > 0) 54 { 55 System.out.println(Thread.currentThread().toString() + "------peter.peng" + count--); 56 } 57 } 58 }); 59 60 thread1.start(); 61 thread1.setPriority(Thread.MAX_PRIORITY);// 设线程的优化级 62 thread2.start(); 63 64 System.out.println(Thread.currentThread().toString()); 65 } 66 67 private static void ThreadJoin() throws InterruptedException 68 { 69 Thread thread1 = new Thread(new Runnable() 70 { 71 int count = 100; 72 73 public void run() 74 { 75 while (count > 0) 76 { 77 System.out.println(Thread.currentThread() + "------peter.peng" + count--); 78 } 79 } 80 }); 81 82 Thread thread2 = new Thread(new Runnable() 83 { 84 int count = 100; 85 86 public void run() 87 { 88 while (count > 0) 89 { 90 System.out.println(Thread.currentThread() + "------peter.peng" + count--); 91 } 92 } 93 }); 94 95 thread1.start(); 96 // thread1.join();//说明thread1要主线程的执行权,这个时候主线程就会冻结了,只到它不要了才会给主线程,如果把它放在后面来执行 97 thread2.start(); 98 thread1.join();// 这时thread1 与thread2交才替出现,只到结束才执行主线程的方法。 99 100 System.out.println(Thread.currentThread() + ":main"); 101 } 102 103 private static void SetDaemon() 104 { 105 Thread thread1 = new Thread(new Runnable() 106 { 107 int count = 0; 108 109 public void run() 110 { 111 while (true) 112 { 113 System.out.println("------peter.peng" + count++); 114 } 115 } 116 }); 117 118 Thread thread2 = new Thread(new Runnable() 119 { 120 int count = 0; 121 122 public void run() 123 { 124 while (true) 125 { 126 System.out.println("------peter.peng" + count++); 127 } 128 } 129 }); 130 thread1.setDaemon(true);// 设为后台线程 131 thread2.setDaemon(true);// 设为后台线程 132 thread1.start(); 133 thread2.start(); 134 System.out.println("over"); 135 } 136 }
posted on 2013-05-15 20:11 peter.peng 阅读(242) 评论(0) 收藏 举报