java.util.concurrent.locks.ReentrantLock is a reentrant mutual exclusion Lock with the same basic behavior and semantics as the implicit monitor lock accessed using synchronized methods and statements, but with extended capabilities.
This example have the same function of the More example of Synchronized Statements with separate objects for locking (the 2nd example), implement with Lock.
package com.example.androidthread;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.app.Activity;
public class MainActivity extends Activity {
Button buttonStart;
TextView textInfoA, textInfoB, textInfoC, textInfoD;
TextView textDuration1, textDuration2;
TextView textDuration3, textDuration4;
String infoMsgA;
String infoMsgB;
String infoMsgC;
String infoMsgD;
ShareClass shareObj = new ShareClass(10);
long startingTime;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
buttonStart = (Button) findViewById(R.id.buttonstart);
textInfoA = (TextView) findViewById(R.id.infoa);
textInfoB = (TextView) findViewById(R.id.infob);
textInfoC = (TextView) findViewById(R.id.infoc);
textInfoD = (TextView) findViewById(R.id.infod);
textDuration1 = (TextView) findViewById(R.id.duration1);
textDuration2 = (TextView) findViewById(R.id.duration2);
textDuration3 = (TextView) findViewById(R.id.duration3);
textDuration4 = (TextView) findViewById(R.id.duration4);
buttonStart.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
infoMsgA = "Thread A\n";
infoMsgB = "Thread B\n";
infoMsgC = "Thread C\n";
infoMsgD = "Thread D\n";
textInfoA.setText(infoMsgA);
textInfoB.setText(infoMsgB);
textInfoC.setText(infoMsgC);
textInfoD.setText(infoMsgD);
Thread thread1 = new Thread(new Runnable() {
boolean stop = false;
@Override
public void run() {
while (!stop) {
if (shareObj.getCounter1() > 0) {
//caution:
//shareObj.counter1 may change here
infoMsgA += "A 1: "
+ shareObj.delayDecCounter1(500) + "\n";
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
textInfoA.setText(infoMsgA);
}
});
} else {
stop = true;
final long endTime1 = System.currentTimeMillis();
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
textDuration1.setText("Duration 1 (reference only): "
+ (endTime1 - startingTime));
}
});
}
}
}
});
Thread thread2 = new Thread(new Runnable() {
boolean stop = false;
@Override
public void run() {
while (!stop) {
if (shareObj.getCounter2() > 0) {
//caution:
//shareObj.counter2 may change here
infoMsgB += "B 2: "
+ shareObj.delayDecCounter2(500) + "\n";
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
textInfoB.setText(infoMsgB);
}
});
} else {
stop = true;
final long endTime2 = System.currentTimeMillis();
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
textDuration2.setText("Duration 2 (reference only): "
+ (endTime2 - startingTime));
}
});
}
}
}
});
//
Thread thread3 = new Thread(new Runnable() {
boolean stop = false;
@Override
public void run() {
while (!stop) {
if (shareObj.getCounter1() > 0) {
//caution:
//shareObj.counter1 may change here
infoMsgC += "C 1: "
+ shareObj.delayDecCounter1(200) + "\n";
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
textInfoC.setText(infoMsgC);
}
});
} else {
stop = true;
final long endTime3 = System.currentTimeMillis();
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
textDuration3.setText("Duration 3 (reference only): "
+ (endTime3 - startingTime));
}
});
}
}
}
});
Thread thread4 = new Thread(new Runnable() {
boolean stop = false;
@Override
public void run() {
while (!stop) {
if (shareObj.getCounter2() > 0) {
//caution:
//shareObj.counter2 may change here
infoMsgD += "D 2: "
+ shareObj.delayDecCounter2(1100) + "\n";
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
textInfoD.setText(infoMsgD);
}
});
} else {
stop = true;
final long endTime4 = System.currentTimeMillis();
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
textDuration4.setText("Duration 4 (reference only): "
+ (endTime4 - startingTime));
}
});
}
}
}
});
//
startingTime = System.currentTimeMillis();
thread1.start();
thread2.start();
thread3.start();
thread4.start();
}
});
}
public class ShareClass {
int counter1;
int counter2;
//Object lock1;
//Object lock2;
Lock lock1;
Lock lock2;
ShareClass(int c) {
counter1 = c;
counter2 = c;
lock1 = new ReentrantLock();
lock2 = new ReentrantLock();
}
public int getCounter1() {
return counter1;
}
public int getCounter2() {
return counter2;
}
public int delayDecCounter1(int delay) {
//do something not access the share obj
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int tmpCounter;
lock1.lock();
try{
tmpCounter = counter1;
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
tmpCounter--;
counter1 = tmpCounter;
}finally{
lock1.unlock();
}
return tmpCounter;
}
public int delayDecCounter2(int delay) {
//do something not access the share obj
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int tmpCounter;
lock2.lock();
try{
tmpCounter = counter2;
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
tmpCounter--;
counter2 = tmpCounter;
}finally{
lock2.unlock();
}
return counter2;
}
}
}
The layout XML, refer to the former exercise of More example of Synchronized Statements with separate objects for locking.
- More example about Thread
No comments:
Post a Comment