synchronized锁
修饰实例方法:
1 2 3
| public synchronized void method(){ ... }
|
被锁的对象是类的实例对象,例如
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
| SynContainer container = new SynContainer();
new Productor(container).start(); new Consumer(container).start();
class Productor extends Thread(){ SynContainer container; public Productor(SynContainer container){ this.SynContainer = container; } }
class Consumer extends Thread(){ SynContainer container; public Productor(SynContainer container){ this.SynContainer = container; } }
class SynContainer(){ public synchronized void method(){ ... } }
|
修饰静态方法:
1 2 3
| public static synchronized void method(){ ... }
|
被锁的对象是类对象
修饰实例对象:
1 2 3
| synchronized (this){ ... }
|
同步代码块,锁住的是该类的实例对象
修饰class对象:
1 2 3
| synchronized (SynContainer.class){ ... }
|
同步代码块,锁住的是该类的类对象
修饰任意实例对象Object:
1 2 3 4
| int num = 10; synchronize (num){ ... }
|
同步代码块,锁住的是配置的实例对象
int对象作为锁
Lock锁
ReentrantLock锁
相比于synchronized锁,Lock锁是显示的,能够显示的定义同步锁来实现同步
ReentrantLock(可重入锁)类实现了Lock,它拥有与synchronized相同的并发性和内存语义,在实现线程安全的控制中,比较常用的是ReentrantLock,可以显示加锁、释放锁
1 2 3 4 5
| reentrantLock.lock();
...
reentrantLock.unlock();
|
例如:
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
| public class Test { public static void main(String[] args) { TestLock1 lock1 = new TestLock1();
new Thread(lock1).start(); new Thread(lock1).start(); new Thread(lock1).start(); } }
class TestLock1 implements Runnable{
int num = 10;
private ReentrantLock reentrantLock = new ReentrantLock();
@Override public void run() { while (true){ try { reentrantLock.lock(); if (num>0){ System.out.println(num--); }else { break; } }finally { reentrantLock.unlock(); }
} } }
|
生产者消费者问题(管程法)
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
| public class Test { public static void main(String[] args) { SynContainer container = new SynContainer();
new Productor(container).start(); new Consumer(container).start(); } }
class Productor extends Thread{ SynContainer container;
public Productor(SynContainer container){ this.container = container; }
@Override public void run() { for (int i = 0; i<100 ; i++) container.push(new Chicken(i)); } }
class Consumer extends Thread{ SynContainer container;
public Consumer(SynContainer container){ this.container = container; }
@Override public void run() { for (int i = 0 ; i<100 ; i++){ container.pop(); } } }
class Chicken{ int id ;
public Chicken(int id){ this.id = id; } }
class SynContainer{ Chicken[] chickens = new Chicken[10]; int count = 0;
public synchronized void push(Chicken chicken){ while (count == chickens.length){ try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } chickens[count] = chicken; count++;
this.notifyAll(); }
public synchronized Chicken pop(){ if (count == 0){ try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } }
count--; Chicken chicken = chickens[count];
this.notifyAll();
return chicken; } }
|