了解 Scala 如何簡化並發編程並繞過陷阱
對於許多(如果不是大多數)Java? 程序員來說
據推測
與 Scala 在
關於本系列
關於本系列 Ted Neward 潛心研究 Scala 編程語言
並發性基礎
在深入研究 Scala 的並發性支持之前
清單
package com
class Producer implements Runnable
{
private Drop drop;
private String importantInfo[] = {
};
public Producer(Drop drop) { this
public void run()
{
for (int i =
{
drop
}
drop
}
}
class Consumer implements Runnable
{
private Drop drop;
public Consumer(Drop drop) { this
public void run()
{
for (String message = drop
message = drop
{
System
}
}
}
class Drop
{
//Message sent from producer to consumer
private String message;
//True if consumer should wait for producer to send message
//false if producer should wait for consumer to retrieve message
private boolean empty = true;
//Object to use to synchronize against so as to not
//
private Object lock = new Object();
public String take()
{
synchronized(lock)
{
//Wait until message is available
while (empty)
{
try
{
lock
}
catch (InterruptedException e) {}
}
//Toggle status
empty = true;
//Notify producer that status has changed
lock
return message;
}
}
public void put(String message)
{
synchronized(lock)
{
//Wait until message has been retrieved
while (!empty)
{
try
{
lock
} catch (InterruptedException e) {}
}
//Toggle status
empty = false;
//Store message
ssage = message;
//Notify consumer that status has changed
lock
}
}
}
public class ProdConSample
{
public static void main(String[] args)
{
Drop drop = new Drop();
(new Thread(new Producer(drop)))
(new Thread(new Consumer(drop)))
}
}
注意
Java 教程
好奇的讀者可能會將此處的代碼與 Java Tutorial 中的代碼進行比較put
和 take
方法Drop
中的 lock 對象
public class ProdConSample
{
public static void main(String[] args)
{
Drop drop = new Drop();
(new Thread(new Producer(drop)))
通過使用私有對象作為鎖定所依托的監測程序
Producer/Consumer 問題的核心非常容易理解
問題的難點在於
關於此主題的全面討論請閱讀 Brian Goetz 的 Java Concurrency in Practice 或 Doug Lea 的 Concurrent Programming in Java(參見 參考資料)
當 Java 編譯器看到 synchronized 關鍵字時
清單
// This is pseudocode
public void put(String message)
{
try
{
monitorenter(lock)
//Wait until message has been retrieved
while (!empty)
{
try
{
lock
} catch (InterruptedException e) {}
}
//Toggle status
empty = false;
//Store message
ssage = message;
//Notify consumer that status has changed
lock
}
finally
{
monitorexit(lock)
}
}
wait() 方法將通知當前線程進入非活動狀態
本文的 代碼下載 部分使用 Java
現在
良好的 Scala 並發性 (v
開始應用 Scala 並發性的一種方法是將 Java 代碼直接轉換為 Scala
清單
object ProdConSample
{
class Producer(drop : Drop)
extends Runnable
{
val importantInfo : Array[String] = Array(
);
override def run() : Unit =
{
importantInfo
drop
}
}
class Consumer(drop : Drop)
extends Runnable
{
override def run() : Unit =
{
var message = drop
while (message !=
{
System
message = drop
}
}
}
class Drop
{
var message : String =
var empty : Boolean = true
var lock : AnyRef = new Object()
def put(x: String) : Unit =
lock
{
// Wait until message has been retrieved
await (empty == true)
// Toggle status
empty = false
// Store message
message = x
// Notify consumer that status has changed
lock
}
def take() : String =
lock
{
// Wait until message is available
await (empty == false)
// Toggle status
empty=true
// Notify producer that staus has changed
lock
// Return the message
message
}
private def await(cond: => Boolean) =
while (!cond) { lock
}
def main(args : Array[String]) : Unit =
{
// Create Drop
val drop = new Drop();
// Spawn Producer
new Thread(new Producer(drop))
// Spawn Consumer
new Thread(new Consumer(drop))
}
}
Producer 和 Consumer 類幾乎與它們的 Java 同類相同
Drop 類同樣類似於它的 Java 版本
注意
最後
但是
Scala 並發性 v
Scala Library Reference 中有一個有趣的包
顧名思義
清單
package com
{
import concurrent
object ProdConSample
{
class Producer(drop : Drop)
extends Runnable
{
val importantInfo : Array[String] = Array(
);
override def run() : Unit =
{
importantInfo
drop
}
}
class Consumer(drop : Drop)
extends Runnable
{
override def run() : Unit =
{
var message = drop
while (message !=
{
System
message = drop
}
}
}
class Drop
{
private val m = new MailBox()
private case class Empty()
private case class Full(x : String)
m send Empty() // initialization
def put(msg : String) : Unit =
{
m receive
{
case Empty() =>
m send Full(msg)
}
}
def take() : String =
{
m receive
{
case Full(msg) =>
m send Empty(); msg
}
}
}
def main(args : Array[String]) : Unit =
{
// Create Drop
val drop = new Drop()
// Spawn Producer
new Thread(new Producer(drop))
// Spawn Consumer
new Thread(new Consumer(drop))
}
}
}
此處
MailBox 有兩個基本操作
因此
put 方法
take 方法
Scala 並發性 v
事實上
清單
package com
{
import concurrent
import concurrent
object ProdConSample
{
class Drop
{
private val m = new MailBox()
private case class Empty()
private case class Full(x : String)
m send Empty() // initialization
def put(msg : String) : Unit =
{
m receive
{
case Empty() =>
m send Full(msg)
}
}
def take() : String =
{
m receive
{
case Full(msg) =>
m send Empty(); msg
}
}
}
def main(args : Array[String]) : Unit =
{
// Create Drop
val drop = new Drop()
// Spawn Producer
spawn
{
val importantInfo : Array[String] = Array(
);
importantInfo
drop
}
// Spawn Consumer
spawn
{
var message = drop
while (message !=
{
System
message = drop
}
}
}
}
}
spawn 方法(通過包塊頂部的 ops 對象導入)接收一個代碼塊(另一個 by
清單
def spawn(p: => Unit) = {
val t = new Thread() { override def run() = p }
t
}
……這再一次強調了 by
ops
事實上
結束語
Scala 為並發性提供了兩種級別的支持
首先
其次
兩個例子中的目標是相同的
但是
From:http://tw.wingwit.com/Article/program/Java/JSP/201311/19570.html