这两天研究一下html5的多线程,根据网上的例子做了一下测试,觉得web worker确实很强大,但一直有一个概念一直不理解,做了个小例子测试一下专用线程和共享线程的区别。
一、专用线程与共享线程概念理解
与网上其他文章类似的文章参考其他相关资料,个人理解,专用线程只适用于当前客户端使用,与其他客户端无关联,适用于本客户端内的多线程使用。共享线程适用于多个客户端之间进行数据的交互和控制,但本身html5中没有类似锁机制,所以无安全可言,全靠个人修为。
二、专用线程测试
测试代码:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>Background Worker Application Example 1: Complicated Number Computation</title>
</head>
<body>
<form>
<div>
计算fibonacci, 请输入计算的数值:<input type="number" id="num" value="10" required="required" /><input type="button" value="计算" onclick="calc()" />
<br><br><div style="float:left;">结果:</div><div id="results" style="border-bottom:1px solid #ccc; width:200px;height:20px;float:left;font-size:9px;"></div>
</div>
</form>
<script>
var worker;
onload = function() {
worker = new Worker('js/numberworker.js');
worker.addEventListener('message', function(event) {
document.getElementById("results").innerHTML = event.data;
}, false);
worker.onerror = function(error) {
alert(error.message);
};
};
var calc = function(){
worker.postMessage(parseInt(document.getElementById("num").value));
document.getElementById("results").innerHTML = "please wait, computing ... ...";
};
</script>
</body>
</html>
numberworker.js 代码:
//关注connect_number在不同的浏览器实例中的值,各自为政,互不干涉 var connect_number = 0; var fibonacci = function(n) { return n < 2 ? n : arguments.callee(n - 1) + arguments.callee(n - 2); }; onmessage = function(event) { connect_number++; var n = parseInt(event.data, 10); var result = "connection "+connect_number+ " is " + fibonacci(n); postMessage(result); };
三、共享线程测试
参考代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Shared worker example: how to use shared worker in HTML5</title>
</head>
<body onload=''>
<output id="response_from_worker"> Shared worker example: how to use shared worker in HTML5 </output>
<br>send instructions to shared worker:
<input type="text" id="inputText" autofocus oninput="postMessageToSharedWorker(this);return false;" />
<script>
var worker = new SharedWorker('js/sharedworker.js');
var log = document.getElementById('response_from_worker');
worker.port.addEventListener('message', function(e) {
//log the response data in web page
log.textContent = e.data;
}, false);
worker.port.start();
worker.port.postMessage('ping from user web page..');
//following method will send user input to sharedworker
function postMessageToSharedWorker(input) {
//define a json object to construct the request
var instructions = {
instruction : input.value
};
worker.port.postMessage(instructions);
}
</script>
</body>
</html>
相关的sharedworker.js代码如下:
/* * define a connect count to trace connecting * this variable will be shared within all connections */ var connect_number = 0; onconnect = function(e) { //关注connect_number 的值的变化,在不同的浏览器实例中,它的值是共享的 connect_number = connect_number + 1; // get the first port here var port = e.ports[0]; port.postMessage('A new connection! The current connection number is ' + connect_number); port.onmessage = function(e) { // get instructions from requester var instruction; if(e.data.instruction) instruction = e.data.instruction; else instruction = e.data; //alert(document.getElementById("inputText").value); var results = execute_instruction(instruction); port.postMessage('Request: ' + instruction + ' Response ' + results + ' from shared worker...'); }; }; /* * this function will be used to execute the instructions send from requester * @param instruction @return */ function execute_instruction(instruction) { var result_value; // implement your logic here // execute the instruction... result_value = instruction; return result_value; }
四、总结
没有什么可以总结的,测试一下代码就明白了,共享线程中connect_number值在多个浏览器实例即多个客户端中是共享的,但专用线程只在本浏览器实例中共享,多个浏览器实例之间不能共享。
个人感觉共享线程在没有相应完善机制保证的情况下,很容易出同步问题,需要多加考虑再用。
五、相关资料
参考了网上比较多的这这篇文章,如下链接:
深入 HTML5 Web Worker 应用实践:多线程编程