java-多线程编程Demo<三>
/**
* 需求:简单的卖票程序。
多个窗口同时买票。
思路:多个窗口就是多个线程。
票就是共享的数据,每个线程都有唯一的它
*/
注意:线程终止的时刻是run方法里的while循环终止的时候。
1 public class TicketDemo {
2
3 public static void main(String[] args) {
4 // TODO Auto-generated method stub
5 //创建共享数据票
6 Ticket t=new Ticket(100);
7 new SellTicket(t).start();
8 new SellTicket(t).start();
9
10 }
11
12 }
13 //票
14 class Ticket
15 {
16 //初始化票为100张
17 private int i=100;
18 public Ticket (int i)
19 {
20 this.i=i;
21 }
22 public int getI() {
23 return i;
24 }
25
26 public void setI(int i) {
27 this.i = i;
28 }
29 }
30 //买票的线程
31 class SellTicket extends Thread
32 {
33 private Ticket t;
34 public SellTicket (Ticket t)
35 {
36 this.t=t;
37 }
38 @Override
39 public void run() {
40 // TODO Auto-generated method stub
41
42
43 while(t.getI()>0)
44 {
45 // try {
46 // Thread.sleep(1000);
47 // } catch (InterruptedException e) {
48 // // TODO Auto-generated catch block
49 // e.printStackTrace();
50 // 使用同步代码块,防止两个窗口打印无法同步
51 synchronized(this.t)
52 {
53 System.out.println(Thread.currentThread().getName()+"剩余票数为"+t.getI());
54 t.setI(t.getI()-1);
55 }
56 }
57
58 }
59
60 }
/**
* 静态的同步函数使用的锁是 该函数所属字节码文件对象
可以用 getClass方法获取,也可以用当前 类名.class 表示即该类。
*/
1 public class StaticSynFunctionDemo {
2 public static void main(String[] args) throws InterruptedException {
3 // TODO Auto-generated method stub
4 Tick t=new Tick();
5 Thread t1=new Thread (t);
6 Thread t2=new Thread(t);
7 //t1将会只执行run的同步代码块
8 t1.start();
9 Thread.sleep(1000);
10 t.flag=false;
11 //t2将只会执行同步方法showTick。
12 t2.start();
13 }
14 }
15 //票:同步代码块与静态方法同步
16 class Tick implements Runnable
17 {
18 private static int i=100;
19 //一个标志位,决定由同步方法执行,还是同步代码块执行
20 boolean flag=true;
21 @Override
22 public void run() {
23 // TODO Auto-generated method stub
24 if(flag)
25 {
26 //拿到flag为true的线程将在这里不停的循环
27 while(true)
28 {
29 try {
30 Thread.sleep(100);
31 } catch (InterruptedException e) {
32 // TODO Auto-generated catch block
33 e.printStackTrace();
34 }
35 synchronized (Tick.class)
36 {
37 System.out.println(Thread.currentThread().getName()+"--run代码块--"+i--);
38 }
39 }
40
41 }else
42 {
43 //拿到flag为false的线程将不停的在这里离循环
44 while(true)
45 {
46 try {
47 Thread.sleep(100);
48 } catch (InterruptedException e) {
49 // TODO Auto-generated catch block
50 e.printStackTrace();
51 }
52 showTick();
53 }
54 }
55
56 }
57 public static synchronized void showTick ()
58 {
59 System.out.println(Thread.currentThread().getName()+"--showTick方法--"+i--);
60 }
61
62 }
/**
* 死锁:常见情景之一:同步的嵌套。即线程x要先拿a,再拿b两个锁才可以执行下去,而线程y刚好相反。
刚好x拿了a锁时,y也拿了b锁,接下来双发互强对方线程手上的锁。
* 总结死锁原因:一:执行同步时要拿两个不同的对象锁
* 二:第二个对象锁被别的线程拿走了,且不还,不释放
* 导致拿了第一个对象锁的线程无法执行下去。
*/
1 public class DeadLockDemo {
2 public static void main(String[] args) throws InterruptedException {
3 // TODO Auto-generated method stub
4 Piao p=new Piao();
5 Thread t1=new Thread(p);
6 Thread t2=new Thread(p);
7 t1.start();
8 Thread.sleep(1);
9 p.flag=false;
10 t2.start();
11 }
12
13 }
14 //票
15 class Piao implements Runnable
16 {
17 private int i=100;
18 //用来做同步的锁
19 Object o=new Object();
20 //标志位,不同线程执行不同标志位下的代码
21 boolean flag=true;
22 @Override
23 public void run() {
24 // TODO Auto-generated method stub
25 if(flag)
26 {
27 while(true)
28 {
29 //flag为true的线程在此执行,
30 //执行下面的第一件事情是拿到对象o的锁
31 synchronized (o)
32 {
33
34 //执行下面的第一件事情是拿到该对象锁piao
35 show();
36 }
37 }
38 }else
39 {
40 while(true)
41 {
42 //flag为false的线程执行下面show()方法
43 //执行show方法的第一个事情是拿到该对象锁piao.
44 this.show();
45 }
46 }
47 }
48 public synchronized void show()
49 {
50 synchronized (o)
51 {
52 try {
53 Thread.sleep(1000);
54 } catch (InterruptedException e) {
55 // TODO Auto-generated catch block
56 e.printStackTrace();
57 }
58 System.out.println(Thread.currentThread().getName()+"-show方法-"+i--);
59 }
60 }
61
62 }