2017-03-31-多线程同步-关键字synchronized 知识点1:
同步关键字:synchronized
在继承的多线程实现中也可以实现对一个类的同一个对象多次操作,只需要在这个继承线程的线程类中将一个类的对象设置为成员变量,再在run()方法中将这个类的方法执行行了,在主线程中创建操作同一个对象的多个线程子类就行了。
对方法加锁,一般不放在run()方法中。
知识点2:
等待和唤醒只能在锁里面使用
wait()某个对象调用时,使线程使方法或方法块的同步锁失效,使得其他的线程的也能够访问这个方法
notify()配合wait()使用,唤醒线程使线程同步锁恢复锁定,其他的线程就不能够进入到这个方法中了。
图文详解1:
窝窝头:
实例1:
模拟线程死锁
密室逃脱
核心代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 package com.share.demo03_31_多线程安全锁;public class Game { public Object key1; public Object key2; public Game () { key1 = new Object (); key2 = new Object (); } public void start (int n) { if (n > 0 ) { System.out.println(Thread.currentThread().getName() + "进入游戏" ); synchronized (key1) { System.out.println(Thread.currentThread().getName() + "得到了key1" ); try { Thread.sleep(1000 ); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (key2) { System.out.println(Thread.currentThread().getName() + "得到了key2" ); try { Thread.sleep(1000 ); } catch (InterruptedException e) { e.printStackTrace(); } } } System.out.println(Thread.currentThread().getName() + "逃脱成功" ); } else { System.out.println(Thread.currentThread().getName() + "进入了游戏" ); synchronized (key2) { System.out.println(Thread.currentThread().getName() + "得到了key2" ); try { Thread.sleep(1000 ); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (key1) { System.out.println(Thread.currentThread().getName() + "得到了key1" ); try { Thread.sleep(1000 ); } catch (InterruptedException e) { e.printStackTrace(); } } } System.out.println(Thread.currentThread().getName() + "逃脱成功" ); } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 package com.share.demo03_31_多线程安全锁;public class GameThread extends Thread { public Game game; public int n; public GameThread (String name, Game game, int n) { super (name); this .game = game; this .n = n; } @Override public void run () { game.start(n); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 package com.share.demo03_31_多线程安全锁;public class GameStart { public static void main (String[] args) { Game game = new Game (); GameThread gt1 = new GameThread ("甲" , game, -1 ); GameThread gt2 = new GameThread ("乙" , game, 1 ); gt1.start(); gt2.start(); } }
实例2:
爱心便当问题,中午打饭: 1、食堂—-将饭菜打包【生产爱心便当】、取出爱心便当 2、最多存放三个爱心便当 3、有三个爱心人士做爱心便当 4、有6个人取便当
核心代码:
老师的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 package com.share.test_3_31;import java.util.Random;public class Test { public static void main (String[] args) { Test t = new Test (); Mess mess = t.new Mess (); People people1 = t.new People ("1号工作人员" ,mess); People people2 = t.new People ("2号工作人员" ,mess); People people3 = t.new People ("3号工作人员" ,mess); Student s1 = t.new Student (mess,"汪洪毅" ); Student s2 = t.new Student (mess,"滕彩俊" ); Student s3 = t.new Student (mess,"林杰" ); Student s4 = t.new Student (mess,"谭小雨" ); Student s5 = t.new Student (mess,"肖峰" ); Student s6 = t.new Student (mess,"徐周" ); people1.start(); people2.start(); people3.start(); s1.start(); s2.start(); s3.start(); s4.start(); s5.start(); s6.start(); } public class Lunch { String food[] = { "凉拌豆腐干" , "烧黄豆" , "回锅肉" , "麻婆豆腐" , "清炒白菜" }; String first; String second; String third; public Lunch () { first = food[new Random ().nextInt(food.length)]; second = food[new Random ().nextInt(food.length)]; third = food[new Random ().nextInt(food.length)]; } public String toString () { return "【" + first + "+" + second + "+" + third + "】" ; } } public class Mess { Lunch box[] = new Lunch [3 ]; int index = 0 ; public synchronized void put (Lunch wucan) { while (index == box.length) { try { this .wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this .notify(); box[index] = wucan; index++; } public synchronized Lunch get () { while (index == 0 ) { try { this .wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this .notify(); index--; return box[index]; } } public class People extends Thread { public Mess mess = null ; public People (String name,Mess mess) { super (name); this .mess = mess; } @Override public void run () { while (true ){ Lunch lunch = new Lunch (); mess.put(lunch); System.out.println(Thread.currentThread().getName()+"制作了爱心便当:" +lunch); try { sleep(new Random ().nextInt(1000 )); } catch (InterruptedException e) { e.printStackTrace(); } } } } public class Student extends Thread { public Mess mess = null ; public Student (Mess mess,String name) { super (name); this .mess = mess; } @Override public void run () { Lunch lunch = mess.get(); System.out.println(Thread.currentThread().getName()+"拿了一份爱心便当" +lunch); } } }
实例3:
窝窝头问题
核心代码:
老师的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 public class ProducerConsumer { public static void main (String[] args) { SyncStack ss = new SyncStack (); Producer p = new Producer (ss); Consumer c = new Consumer (ss); new Thread (p).start(); new Thread (p).start(); new Thread (p).start(); new Thread (c).start(); } } class WoTou { int id; WoTou(int id) { this .id = id; } public String toString () { return "WoTou : " + id; } } class SyncStack { int index = 0 ; WoTou[] arrWT = new WoTou [6 ]; public synchronized void push (WoTou wt) { System.out.println(index); while (index == arrWT.length) { try { this .wait(); System.out.println(Thread.currentThread().getName()); } catch (InterruptedException e) { e.printStackTrace(); } } this .notifyAll(); arrWT[index] = wt; index++; } public synchronized WoTou pop () { System.out.println(arrWT.length); while (index == 0 ) { try { this .wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this .notifyAll(); index--; return arrWT[index]; } } class Producer implements Runnable { SyncStack ss = null ; Producer(SyncStack ss) { this .ss = ss; } public void run () { for (int i = 0 ; i < 20 ; i++) { WoTou wt = new WoTou (i); ss.push(wt); System.out.println("生产了:" + wt); try { Thread.sleep((int ) (Math.random() * 200 )); } catch (InterruptedException e) { e.printStackTrace(); } } } } class Consumer implements Runnable { SyncStack ss = null ; Consumer(SyncStack ss) { this .ss = ss; } public void run () { for (int i = 0 ; i < 20 ; i++) { WoTou wt = ss.pop(); System.out.println("消费了: " + wt); try { Thread.sleep((int ) (Math.random() * 1000 )); } catch (InterruptedException e) { e.printStackTrace(); } } } }