同步方法
死锁的概念
-
互斥条件:一个资源每次只能被一个进程使用
-
请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放
-
不剥夺条件:进程已获得的资源,在未使用完之前,不能强行剥夺
-
循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系
synchronized 方法
使用synchronized方法和synchronized块
每个synchronized方法都必须获得调用该方法的对象的锁才能执行,否则线程会阻塞,方法一旦执行会独占该锁,知道该方法返回才释放该锁
lock方法
定义lock锁,在使用同步资源前加锁,在使用结束后释放该锁
1 //定义lock锁 2 private final ReentrantLock lock = new ReentrantLock();
加锁
1 lock.lock();//加锁
解锁
lock.unlock();//解锁
一般配合try catch使用,解锁放在finally中
1 //测试lock锁 2 public class TestLock { 3 public static void main(String[] args) { 4 TestLock2 testLock2 = new TestLock2(); 5 new Thread(testLock2).start(); 6 new Thread(testLock2).start(); 7 new Thread(testLock2).start(); 8 } 9 } 10 11 class TestLock2 implements Runnable{ 12 int tickstnum =10; 13 //定义lock锁 14 private final ReentrantLock lock = new ReentrantLock(); 15 @Override 16 public void run() { 17 while (true){ 18 19 try { 20 lock.lock();//加锁 21 22 if (tickstnum > 0) { 23 try { 24 Thread.sleep(1000); 25 } catch (InterruptedException e) { 26 e.printStackTrace(); 27 } 28 System.out.println(tickstnum--); 29 } else { 30 break; 31 } 32 }finally { 33 lock.unlock();//解锁 34 } 35 } 36 37 } 38 }
synchronized与lock
-
lock是显式锁,手动开启和关闭,synchronized是隐式锁,出了作用域自动释放
-
lock只有代码锁,synchronized有代码块和方法锁
-
lock性能更好
利用缓冲区解决,管程法
定义缓冲区,定义拿取函数
使用synchronized定义
1 //缓冲区 2 class SynContainer{ 3 //容器大小 4 Chicken[] chickens = new Chicken[10]; 5 //容器计数器 6 int count = 0; 7 //生产者放入产品 8 public synchronized void push(Chicken chicken) throws InterruptedException { 9 //如果容器满了 需要等待消费者消费 10 if(count == chickens.length){ 11 //通知消费者等待 12 this.wait(); 13 } 14 //如果没满 可以丢入产品 15 chickens[count] = chicken; 16 count++; 17 //通知消费者消费 18 this.notifyAll(); 19 } 20 21 22 //消费者取走产品 23 public synchronized Chicken pop() throws InterruptedException { 24 //判断能否消费 25 if (count == 0){ 26 //等待生产者生产 27 this.wait(); 28 } 29 //如果可以生产 30 count--; 31 Chicken chicken = chickens[count]; 32 33 34 //吃完了 通知生产者生产 35 this.notifyAll(); 36 return chicken; 37 } 38 }
定义生产者消费者进程 通过缓冲区调用该进程
1 //生产者消费者模型-> 利用缓冲区解决:管程法 2 public class TestPC { 3 public static void main(String[] args) { 4 SynContainer container = new SynContainer(); 5 new Producer(container).start(); 6 new Consumer(container).start(); 7 } 8 } 9 10 //生产者 11 class Producer extends Thread{ 12 SynContainer container; 13 public Producer(SynContainer container){ 14 this.container = container; 15 } 16 //生产 17 @Override 18 public void run() { 19 for (int i = 0; i < 100; i++) { 20 System.out.println("生产了"+i+"只鸡"); 21 try { 22 container.push(new Chicken(i)); 23 } catch (InterruptedException e) { 24 e.printStackTrace(); 25 } 26 } 27 } 28 } 29 30 //消费者 31 class Consumer extends Thread{ 32 SynContainer container; 33 public Consumer(SynContainer container){ 34 this.container = container; 35 } 36 //消费 37 @Override 38 public void run() { 39 for (int i = 0; i < 100; i++) { 40 try { 41 System.out.println("消费了-->"+container.pop().id+"只鸡"); 42 } catch (InterruptedException e) { 43 e.printStackTrace(); 44 } 45 } 46 } 47 } 48 49 //产品 50 class Chicken{ 51 int id; 52 53 public Chicken(int id) { 54 this.id = id; 55 } 56 }
表演者与观众同步进程
1 public class TestPc2 { 2 public static void main(String[] args) { 3 TV tv = new TV(); 4 new Player(tv).start(); 5 new Watcher(tv).start(); 6 } 7 } 8 9 //生产者->演员 10 class Player extends Thread{ 11 TV tv; 12 public Player(TV tv){ 13 this.tv = tv; 14 } 15 @Override 16 public void run() { 17 for (int i = 0; i < 20; i++) { 18 if(i%2==0){ 19 tv.play("快乐大本营"); 20 }else{ 21 tv.play("抖音"); 22 } 23 } 24 } 25 } 26 //消费者->观众 27 class Watcher extends Thread{ 28 TV tv; 29 public Watcher(TV tv){ 30 this.tv = tv; 31 } 32 @Override 33 public void run() { 34 for (int i = 0; i < 20; i++) { 35 tv.watch(); 36 } 37 } 38 } 39 //产品->节目 40 class TV{ 41 String name; 42 boolean flag = true; 43 44 //表演 45 public synchronized void play(String name){ 46 if (!flag){ 47 try { 48 this.wait(); 49 } catch (InterruptedException e) { 50 e.printStackTrace(); 51 } 52 } 53 System.out.println("表演了 "+name); 54 this.notifyAll(); 55 this.name = name; 56 this.flag = !this.flag; 57 58 } 59 //观看 60 public synchronized void watch(){ 61 if(flag){ 62 try { 63 this.wait(); 64 } catch (InterruptedException e) { 65 e.printStackTrace(); 66 } 67 } 68 System.out.println("观看了 "+name); 69 this.notifyAll(); 70 this.flag = !this.flag; 71 72 } 73 }
线程池
1 //测试线程池 2 public class TestPool { 3 public static void main(String[] args) { 4 //1.创建线程池 5 //newFixedThreadPool参数为:线程池大小 6 ExecutorService service = Executors.newFixedThreadPool(10); 7 8 service.execute(new MyThread()); 9 service.execute(new MyThread()); 10 service.execute(new MyThread()); 11 service.execute(new MyThread()); 12 //2.关闭连接 13 service.shutdown(); 14 } 15 } 16 17 18 class MyThread implements Runnable{ 19 @Override 20 public void run() { 21 22 System.out.println(Thread.currentThread().getName()); 23 24 } 25 }
标签:同步,container,tv,lock,void,day22,new,方法,public From: https://www.cnblogs.com/GUGUZIZI/p/16870956.html