java 執行緒通訊的兩種方法
阿新 • • 發佈:2019-01-23
先講如何通訊: 再講 如何 同步。網上的程式碼是有問題的。我註釋了出來。
第一 。\執行緒 共用 一個 稀缺變數:
1、 繼承至 thread 類
public
class
Innersharethread {
public
static
void
main(String[] args) {
Mythread mythread =
new
Mythread();
mythread.getThread().start();
mythread.getThread().start();
mythread.getThread().start();
mythread.getThread().start();
}
}
class
Mythread {
int
index =
0
;
private
class
InnerThread
extends
Thread {
public
synchronized
void
run() { //這是不同步的!!!這裡的synchronized 加不加 結果都不能同步,因為加的位置不對。同步請見後面。
//執行緒很隨意的就可以拿到index;
while
(
true
) {
System.out.println(Thread.currentThread().getName() +
"is running and index is "
+ index++);
}
}
}
public
Thread getThread() {
return
new
InnerThread();
}
}
2、通過實現Runnable介面實現執行緒的共享變數
public
class
Interfacaesharethread {
public
static
void
main(String[] args) {
Mythread mythread =
new
Mythread();
new
Thread(mythread).start();
new
Thread(mythread).start();
new
Thread(mythread).start();
new
Thread(mythread).start();
}
}
/* 實現Runnable介面 */
class Mythread
implements Runnable {
int index = 0;
public
synchronized void run() {//這是不同步的!!這裡加上 synchronized 就便成只有0號執行緒再跑了,其他的都沒法獲得資源。
//可是如果不加,大家都可以隨意搶奪index,無法同步
while (true)
System.out.println(Thread.currentThread().getName() + "is running and the index is " + index++);
}
}
第二種,通過pipe 的方式,這種方式只能一個負責輸出,一個負責接收。這樣單向的。
public
class
CommunicateWhitPiping {
public
static
void
main(String[] args) {
/**
* 建立管道輸出流
*/
PipedOutputStream pos =
new
PipedOutputStream();
/**
* 建立管道輸入流
*/
PipedInputStream pis =
new
PipedInputStream();
try
{
/**
* 將管道輸入流與輸出流連線 此過程也可通過過載的建構函式來實現
*/
pos.connect(pis);
}
catch
(IOException e) {
e.printStackTrace();
}
/**
* 建立生產者執行緒
*/
Producer p =
new
Producer(pos);
/**
* 建立消費者執行緒
*/
Consum c =
new
Consum(pis);
/**
* 啟動執行緒
*/
p.start();
c.start();
}
}
/**
* 生產者執行緒(與一個管道輸入流相關聯)
*
*/
class
Producer
extends
Thread {
private
PipedOutputStream pos;
public
Producer(PipedOutputStream pos) {
this
.pos = pos;
}
public
void
run() {
int
i =
8
;
try
{
pos.write(i);
}
catch
(IOException e) {
e.printStackTrace();
}
}
}
/**
* 消費者執行緒(與一個管道輸入流相關聯)
*
*/
class
Consum
extends
Thread {
private
PipedInputStream pis;
public
Consum(PipedInputStream pis) {
this
.pis = pis;
}
public
void
run() {
try
{
System.out.println(pis.read());
}
catch
(IOException e) {
e.printStackTrace();
}
}
}
這樣兩種方式搞定了。後面會再寫一篇socket 來實現多執行緒程式設計 和 python 在多執行緒上的實現。
第一例子:
1、相當於執行緒的工廠創造了四個相同的操作程式碼塊,在每個執行緒自己私有空間裡,所以加不加 synchronized (鎖) 根本沒用。
這裡的想法是要鎖住 稀缺資源 index;
2、synchronized 關鍵字不能加在 while 之外, 因為 加在那裡,while沒執行完畢,執行緒是不會放棄鎖的。
正確的做法:
public
class
Innersharethread {
public
static
void
main(String[] args) {
Mythread mythread =
new
Mythread();
mythread.getThread().start();
mythread.getThread().start();
mythread.getThread().start();
mythread.getThread().start();
}
}
class
Mythread {
int
index =
0
;
private
class
InnerThread
extends
Thread {
public
void
run() {
while
(
true
) {
synchronized (MyThread.this){//獲得這個整個物件的鎖
System.out.println(Thread.currentThread().getName() +
"is running and index is "
+ index++);
}
}
}
}
public
Thread getThread() {
return
new
InnerThread();
}
}
或者用 synchronized 鎖住 爭用資源的語句塊。
如下,也是可行的:
public
class
Innersharethread {
public
static
void
main(String[] args) {
Mythread mythread =
new
Mythread();
mythread.getThread().start();
mythread.getThread().start();
mythread.getThread().start();
mythread.getThread().start();
}
}
class
Mythread {
int
index =
0
;
public synchronized int add(){
return index++; // 鎖住爭用資源的語句塊。
}
private
class
InnerThread
extends
Thread {
public
void
run() {
while
(
true
) {
System.out.println(Thread.currentThread().getName() +
"is running and index is "
+ add());
}
}
}
public
Thread getThread() {
return
new
InnerThread();
}
}
ok,後面的 runnable 的介面的更改方式我就直接給出答案了。也是一樣的。
public
class
Interfacaesharethread {
public
static
void
main(String[] args) {
Mythread mythread =
new
Mythread();
new
Thread(mythread).start();
new
Thread(mythread).start();
new
Thread(mythread).start();
new
Thread(mythread).start();
}
}
/* 實現Runnable介面 */
class Mythread
implements Runnable {
int index = 0;
public void run() {
while (true)
synchronized (this){ // 注意哈,這裡的是this 不用在加 (類名.this)的格式了,因為主要是為了鎖住稀缺資源,
//而第一例的實現是通過內部類來實現的,所以要拿到外部類的物件鎖才行。
System.out.println(Thread.currentThread().getName() + "is running and the index is " + index++);
}
}
}
或者 :
class Mythread
implements Runnable {
int index = 0;
public synchronized int add(){
return index++;
}
public void run() {
while (true)
System.out.println(Thread.currentThread().getName() + "is running and the index is " + add());
}
}
}