线程(续)
线程同步
当两个或两个以上的线程需要共享资源,它们需要某种方法来确定资源在某一刻仅被一个线程占用。达到此目的的过程叫做同步(synchronization)
可以用两种方法同步化代码。两者都包括synchronized关键字的运用
同步方法
在某一时刻,必须限制只有一个线程可以支配它。为此,只需在方法定义前加上关键字synchronized
synchronized void call(String msg) { //TO DO }
同步语句
类似C#中的lock(),将需要同步的代码块放入synchronized(obj) { ... }
class Caller implements Runnable { String msg; Callme target; public void run() { synchronized (target) { target.call(msg); } } }
线程间通讯
Java包含了通过wait( ),notify( )和notifyAll( )方法实现的一个进程间通信机制。这三个方法仅在synchronized方法中才能被调用
- wait( ) 告知被调用的线程放弃管程进入睡眠直到其他线程进入相同管程并且调用notify( )。
- notify( ) 恢复相同对象中第一个调用 wait( ) 的线程。
- notifyAll( ) 恢复相同对象中所有调用 wait( ) 的线程。具有最高优先级的线程最先运行。
适用于简单的生产者-消费者模式(当一个线程正在产生数据而另一个程序正在消费它)
一个中间序列
class PQueue { int n; boolean valueSet = false; synchronized int get() { if (!valueSet) { try { wait(); } catch (InterruptedException e) { System.out.println("InterruptedException caught"); } } System.out.println("Got: " + n); valueSet = false; notify(); return n; } synchronized void put(int n) { if (valueSet) try { wait(); } catch (InterruptedException e) { System.out.println("InterruptedException caught"); } this.n = n; valueSet = true; System.out.println("Put: " + n); notify(); } }
生产者
class Producer implements Runnable { PQueue q; Producer(PQueue q) { this.q = q; new Thread(this, "Producer").start(); } public void run() { int i = 0; while (i < 10) { q.put(i++); }
q.put(i++);
}
}
消费者
class Consumer implements Runnable { PQueue q; Consumer(PQueue q) { this.q = q; new Thread(this, "Consumer").start(); } public void run() { int i = 0; while (i>=0) { i =q.get(); } } }
PQueue q = new PQueue(); new Producer(q); new Consumer(q);
死锁
死锁发生在当两个线程对一对同步对象有循环依赖关系时
是多线程开发特别需要注意的
线程挂起、恢复、中止
http://www.weixueyuan.net/view/6034.html
つづけ