ReentrantReadWriteLock讓不同的讀取執行緒可以並發執行,但還是阻塞讀取直行緒vs 寫入執行緒,以及寫入執行緒vs. 寫入執行緒的狀況
採用程式碼:
int shareResource;
private ReentrantReadWriteLock mLock = new ReentrantReadWriteLock();
publicvoid changeState(){
mLock.writeLock().lock();
try{
shareResource++;
}
finally{
mLock.writeLock().unlock();
}
}
public int readState(){
mLock.readLock().lock();
try{
return shareResource;
}
finally{
mLock.readLock().unlock();
}
}
---------------------------
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.jing.example.nknu_.multiprocess_p24">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.jing.example.nknu_.multiprocess_p24.MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<include layout="@layout/content_main" />
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margin"
android:src="@android:drawable/ic_dialog_email" />
</android.support.design.widget.CoordinatorLayout>
content_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="com.jing.example.nknu_.multiprocess_p24.MainActivity"
tools:showIn="@layout/activity_main">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Start"
android:id="@+id/button"
android:onClick="Start"
android:layout_alignTop="@+id/button2"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Large Text"
android:id="@+id/textView"
android:maxLines="15"
android:lines="15"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="clear"
android:id="@+id/button2"
android:onClick="clear"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="68dp" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:ems="10"
android:id="@+id/editText3"
android:layout_above="@+id/editText4"
android:layout_alignLeft="@+id/button2"
android:layout_alignStart="@+id/button2" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:ems="10"
android:id="@+id/editText2"
android:layout_below="@+id/editText"
android:layout_alignLeft="@+id/editText"
android:layout_alignStart="@+id/editText" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:ems="10"
android:id="@+id/editText"
android:layout_alignTop="@+id/textView"
android:layout_alignLeft="@+id/editText3"
android:layout_alignStart="@+id/editText3"
android:layout_marginTop="83dp" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:ems="10"
android:id="@+id/editText4"
android:layout_above="@+id/textView3"
android:layout_alignLeft="@+id/editText3"
android:layout_alignStart="@+id/editText3" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="第一類別"
android:id="@+id/textView2"
android:layout_below="@+id/editText2"
android:layout_alignLeft="@+id/editText4"
android:layout_alignStart="@+id/editText4" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="第二類別"
android:id="@+id/textView3"
android:layout_alignBottom="@+id/textView"
android:layout_alignLeft="@+id/editText4"
android:layout_alignStart="@+id/editText4" />
</RelativeLayout>
MainActivity.java
package com.jing.example.nknu_.multiprocess_p24;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class MainActivity extends AppCompatActivity {
String st;
private int shareResource = 0;
private int shareResource2 = 0;
private ReentrantReadWriteLock mLock = new ReentrantReadWriteLock();
private ReentrantLock mlock2 = new ReentrantLock();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
//開始執行續 t1執行緒先開始 後開t2執行緒
public void Start(View v){
//開啟第一個執行緒
RaceCondition race = new RaceCondition();
race.startTwoThreads();
//開啟第二個執行緒
// RaceCondition2 race2 = new RaceCondition2();
//race2.startTwoThreads();
}
//用於清除st 以及 text UI內容
public void clear(View v){
TextView txv;
txv = (TextView)findViewById(R.id.textView);
txv.setText("");
shareResource= 0;
st = "";
}
//-------------------------------------------------第一類別鎖
public void changeState(){
mLock.writeLock().lock();
try {
runOnUiThread(new Runnable() {
public void run() {
EditText edtxv;
edtxv = (EditText) findViewById(R.id.editText);
edtxv.setText("寫入狀態");
}
});
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() {
@Override
public void run() {
EditText edtxv;
edtxv = (EditText) findViewById(R.id.editText);
edtxv.setText("");
}
});
}
finally{
mLock.writeLock().unlock();
}
}
public String readState(int classnum){
mLock.readLock().lock();
try{
if(classnum==1){
runOnUiThread(new Runnable() {
public void run() {
EditText edtxv;
edtxv = (EditText) findViewById(R.id.editText2);
edtxv.setText("讀取狀態");
}
});
classnum=0;
}else if(classnum==2){
runOnUiThread(new Runnable() {
public void run() {
EditText edtxv;
edtxv = (EditText) findViewById(R.id.editText3);
edtxv.setText("讀取狀態");
}
});
classnum=0;
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() {
@Override
public void run() {
EditText edtxv;
EditText edtxv2;
edtxv = (EditText) findViewById(R.id.editText2);
edtxv2 = (EditText)findViewById(R.id.editText3);
edtxv.setText("");
edtxv2.setText("");
}
});
return "執行緒";
}
finally{
mLock.readLock().unlock();
}
}
/*
public void changeState(){
mLock.lock();
try{
runOnUiThread(new Runnable() {
public void run() {
EditText edtxv;
edtxv = (EditText) findViewById(R.id.editText);
edtxv.setText("第" + "1" + "執行緒");
}
});
Thread.sleep(150);
runOnUiThread(new Runnable() {
@Override
public void run() {
EditText edtxv;
edtxv = (EditText) findViewById(R.id.editText);
edtxv.setText("");
}
});
} catch (InterruptedException e) {
e.printStackTrace();
} finally{
mlock.unlock();
}
}
*/
/*
public void changeState2(){
mlock.lock();
try{
System.out.println("第二執行緒");
runOnUiThread(new Runnable() {
public void run() {
EditText edtxv;
edtxv = (EditText) findViewById(R.id.editText2);
edtxv.setText("第" + "2" + "執行緒");
}
});
Thread.sleep(150);
runOnUiThread(new Runnable() {
@Override
public void run() {
EditText edtxv;
edtxv = (EditText) findViewById(R.id.editText2);
edtxv.setText("");
}
});
} catch (InterruptedException e) {
e.printStackTrace();
} finally{
mlock.unlock();
}
}
*/
//----------------------------------------------------------------------------------------
/*
//--------------------------------------第二類別鎖
public void changeState3(){
mlock2.lock();
try{
System.out.println("第三執行緒");
runOnUiThread(new Runnable() {
public void run() {
EditText edtxv;
edtxv = (EditText) findViewById(R.id.editText3);
edtxv.setText("第" + "3" + "執行緒");
}
});
Thread.sleep(150);
runOnUiThread(new Runnable() {
@Override
public void run() {
EditText edtxv;
edtxv = (EditText) findViewById(R.id.editText3);
edtxv.setText("");
}
});
} catch (InterruptedException e) {
e.printStackTrace();
} finally{
mlock2.unlock();
}
}
public void changeState4(){
mlock2.lock();
try{
System.out.println("第四執行緒");
runOnUiThread(new Runnable() {
public void run() {
EditText edtxv;
edtxv = (EditText) findViewById(R.id.editText4);
edtxv.setText("第" + "4" + "執行緒");
}
});
Thread.sleep(150);
runOnUiThread(new Runnable() {
@Override
public void run() {
EditText edtxv;
edtxv = (EditText) findViewById(R.id.editText4);
edtxv.setText("");
}
});
} catch (InterruptedException e) {
e.printStackTrace();
} finally{
mlock2.unlock();
}
}
//--------------------------------------------------------------
*/
//第一個類別
public class RaceCondition{
public void startTwoThreads(){
Thread t1 = new Thread(new Runnable(){
@Override
public void run(){
changeState();
st = st + String.valueOf(shareResource) + "第一執行緒" + "\n";
final String ThST = st;
//執行UI執行緒
runOnUiThread(new Runnable() {
public void run() {
TextView txv;
txv = (TextView)findViewById(R.id.textView);
txv.setText(ThST);
}
});
}
});
t1.start();
Thread t2 = new Thread(new Runnable(){
@Override
public void run(){
readState(1);
st = st + String.valueOf(shareResource2) + "第二執行緒" + "\n";
final String ThST = st;
//執行UI執行緒
runOnUiThread(new Runnable() {
public void run() {
TextView txv;
txv = (TextView)findViewById(R.id.textView);
txv.setText(ThST);
}
});
}
});
t2.start();
Thread t3 = new Thread(new Runnable(){
@Override
public void run(){
readState(2);
st = st + String.valueOf(shareResource2) + "第三執行緒" + "\n";
final String ThST = st;
//執行UI執行緒
runOnUiThread(new Runnable() {
public void run() {
TextView txv;
txv = (TextView)findViewById(R.id.textView);
txv.setText(ThST);
}
});
}
});
t3.start();
}
}
/*
//第二個類別
public class RaceCondition2{
public void startTwoThreads(){
Thread t3 = new Thread(new Runnable(){
@Override
public void run(){
changeState3();
st = st + String.valueOf(shareResource) + "第三執行緒" + "\n";
final String ThST = st;
//執行UI執行緒
runOnUiThread(new Runnable() {
public void run() {
TextView txv;
txv = (TextView)findViewById(R.id.textView);
txv.setText(ThST);
}
});
}
});
t3.start();
Thread t4 = new Thread(new Runnable(){
@Override
public void run(){
changeState4();
st = st + String.valueOf(shareResource) + "第四執行緒" + "\n";
final String ThST = st;
//執行UI執行緒
runOnUiThread(new Runnable() {
public void run() {
TextView txv;
txv = (TextView)findViewById(R.id.textView);
txv.setText(ThST);
}
});
}
});
t4.start();
}
}
*/
}