java多线程间的通信传值_Java 多线程之间的通信

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

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

packagecn.itcast.day5.thread;//一进一出

public class线程通信

{public static voidmain(String[] args)

{

Resouce resouce= newResouce();

Input input= newInput(resouce);

OutPut outPut= newOutPut(resouce);

Thread thread1= newThread(input);

Thread thread2= newThread(outPut);

thread1.start();

thread2.start();

}

}classResouce

{publicString name;publicString sex;

}class Input implementsRunnable

{

Resouce resouce;

Input(Resouce resouce)

{this.resouce =resouce;

}

@Overridepublic voidrun()

{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 implementsRunnable

{

Resouce resouce;

OutPut(Resouce resouce)

{this.resouce =resouce;

}

@Overridepublic voidrun()

{while (true)

{synchronized (Input.class) //两个线程的锁只要是一个object 在内存中的字节码

{

System.out.println(Thread.currentThread()+ "-----:" + resouce.name + ":" +resouce.sex);

}

}

}

}

进水与进水的案例

如果要达到一进一去,交替出现而不是从上一案例一样,则得用到 wait()     notify()  notityAll(),理解这几个意义

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 packagecn.itcast.day5.thread;2

3 //一进一出

4 public class线程通信5 {6 public static voidmain(String[] args)7 {8 Resouce resouce = newResouce();9 Input input = newInput(resouce);10 OutPut outPut = newOutPut(resouce);11

12 Thread thread1 = newThread(input);13 Thread thread2 = newThread(outPut);14

15 thread1.start();16 thread2.start();17 }18 }19

20 classResouce21 {22 publicString name;23 publicString sex;24 boolean flag=false;25 }26

27 class Input implementsRunnable28 {29 Resouce resouce;30

31 Input(Resouce resouce)32 {33 this.resouce =resouce;34 }35

36 @Override37 public voidrun()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,这时线程149 //就会等待,同是叫醒线程2.50 //由于flag=true 则线程2不会等待,就会执行输出语句,输出完后,flag=false,这时线程2就会等待,同时叫醒线程151 //这时就会执行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 implementsRunnable76 {77 Resouce resouce;78

79 OutPut(Resouce resouce)80 {81 this.resouce =resouce;82 }83

84 @Override85 public voidrun()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 方法进行同步。

生者消费者的例子

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 packagenet.nw.entites;2

3 public classThreadDemo_Product_Customer {4

5 public static voidmain(String[] args) {6

7 Resource resource = newResource();8 Product product = newProduct(resource);9 Customer customer = newCustomer(resource);10

11 Thread t1 = newThread(product);12 Thread t2 = newThread(customer);13 Thread t3 = newThread(product);14 Thread t4 = newThread(customer);15

16 t1.start();17 t2.start();18 t3.start();19 t4.start();20 }21 }22

23 classResource {24 publicString name;25 public booleanflag;26 public int count = 0;27

28 public synchronized voidSet(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 voidgetOut() {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 implementsRunnable {63 Resource resource;64

65 Product(Resource resource) {66 this.resource =resource;67 }68

69 @Override70 public voidrun() {71 resource.Set("pc");72 }73 }74

75 class Customer implementsRunnable {76 Resource resource;77

78 Customer(Resource resource) {79 this.resource =resource;80 }81

82 @Override83 public voidrun() {84 resource.getOut();85 }86

87 }

两个以上线程的消费与生产关系

JdK1.5 新特性的多线程操作

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 packagenet.nw.entites;2

3 importjava.util.concurrent.locks.Condition;4 importjava.util.concurrent.locks.Lock;5 importjava.util.concurrent.locks.ReentrantLock;6

7 public classThreadDemo_Product_Customer {8

9 public static voidmain(String[] args) {10

11 Resource resource = newResource();12 Product product = newProduct(resource);13 Customer customer = newCustomer(resource);14

15 Thread t1 = newThread(product);16 Thread t2 = newThread(customer);17 Thread t3 = newThread(product);18 Thread t4 = newThread(customer);19

20 t1.start();21 t2.start();22 t3.start();23 t4.start();24 }25 }26

27 classResource {28 publicString name;29 public booleanflag;30 public int count = 0;31

32 final Lock lock = newReentrantLock();33 final Condition notFull =lock.newCondition();34 final Condition notEmpty =lock.newCondition();35

36 public voidSet(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 voidgetOut() {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 implementsRunnable {81 Resource resource;82

83 Product(Resource resource) {84 this.resource =resource;85 }86

87 @Override88 public voidrun() {89 resource.Set("pc");90 }91 }92

93 class Customer implementsRunnable {94 Resource resource;95

96 Customer(Resource resource) {97 this.resource =resource;98 }99

100 @Override101 public voidrun() {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,然后在验证循环体的条件。

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 packagenet.nw.entites;2

3 importjava.util.concurrent.locks.Condition;4 importjava.util.concurrent.locks.Lock;5 importjava.util.concurrent.locks.ReentrantLock;6

7 public classThreadDemo_Product_Customer {8

9 public static voidmain(String[] args) {10

11 Resource resource = newResource();12 Product product = newProduct(resource);13 Customer customer = newCustomer(resource);14

15 Thread t1 = newThread(product);16 Thread t2 = newThread(customer);17 Thread t3 = newThread(product);18 Thread t4 = newThread(customer);19 t1.start();20 t2.start();21

22 //t3.start();23 //t4.start();

24 }25 }26

27 classResource {28 publicString name;29 public booleanflag;30 public boolean conditionFlag = true;31 public int count = 0;32

33 final Lock lock = newReentrantLock();34 final Condition notFull =lock.newCondition();35 final Condition notEmpty =lock.newCondition();36

37 public voidSet(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 voidgetOut() {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 implementsRunnable {94 Resource resource;95

96 Product(Resource resource) {97 this.resource =resource;98 }99

100 @Override101 public voidrun() {102 resource.Set("pc");103 }104 }105

106 class Customer implementsRunnable {107 Resource resource;108

109 Customer(Resource resource) {110 this.resource =resource;111 }112

113 @Override114 public voidrun() {115 resource.getOut();116 }117

118 }

多线程安全通信的线程中断

线程的join   setDaemon  yield

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 packagecn.itcast.day5.thread;2

3 class Demo1 implementsRunnable4 {5 private int count = 100;6

7 @Override8 public voidrun()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 classThreadJionYield19 {20 public static void main(String[] args) throwsInterruptedException21 {22 //SetDaemon();//设为后台线程23 //ThreadJoin();//join可以用来时加入线程,遇到一个线程的Join主线程冻结,其它的不变,只到Join这个线程结束,主线程再执行。24 //SetPriority();//设置线程的优势级

25 Thread thread1 = new Thread(new Demo1());//yield让当前线程停止执行另一个线程。

26 Thread thread2 = new Thread(newDemo1());27

28 thread1.start();29 thread2.start();30 }31

32 private static voidSetPriority()33 {34 Thread thread1 = new Thread(newRunnable()35 {36 int count = 100;37

38 public voidrun()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(newRunnable()48 {49 int count = 100;50

51 public voidrun()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() throwsInterruptedException68 {69 Thread thread1 = new Thread(newRunnable()70 {71 int count = 100;72

73 public voidrun()74 {75 while (count > 0)76 {77 System.out.println(Thread.currentThread() + "------peter.peng" + count--);78 }79 }80 });81

82 Thread thread2 = new Thread(newRunnable()83 {84 int count = 100;85

86 public voidrun()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 voidSetDaemon()104 {105 Thread thread1 = new Thread(newRunnable()106 {107 int count = 0;108

109 public voidrun()110 {111 while (true)112 {113 System.out.println("------peter.peng" + count++);114 }115 }116 });117

118 Thread thread2 = new Thread(newRunnable()119 {120 int count = 0;121

122 public voidrun()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 }

线程的Join,setDaemon yield

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值