線程鎖,解決併發請求

(1)

package com.example.multidownload;



import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;


import android.os.Handler;


public class WriteThread extends Thread {
private String fileName;
private int startPosition;
private boolean state=true;
private int times;
private Handler handler;
public WriteThread(String fileName,int startPosition,Handler handler) {
super();
this.fileName=fileName;
this.startPosition=startPosition;
this.handler=handler;
}
@Override
public void run() {
super.run();
try {
RandomAccessFile randomAccessFile = new RandomAccessFile(fileName, "rwd");
randomAccessFile.seek(startPosition);
while (times<100) {
              if(!state)
              {
              //java.lang.IllegalMonitorStateException: object not locked by thread before wait()
              //即this.wait();周圍也要加鎖,不然會報上面的錯

              synchronized (this) {
              System.out.println(WriteThread.this.getName()+"線程等待中........"+times);
              handler.sendEmptyMessage(0);
              this.wait();
}
             
              }
              System.out.println(WriteThread.this.getName()+"線程執行中........"+times);
              randomAccessFile.writeChars("hello:"+WriteThread.this.getName()+"="+times+"\r\n");
             
              times++;
              Thread.sleep(100);
}
handler.sendEmptyMessage(1);
randomAccessFile.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void pauseWrite()
{
this.state=false;
}
public void resumeWrite()
{
this.state=true;
//java.lang.IllegalMonitorStateException: object not locked by thread before notifyAll()
//即this.notifyAll();外圍也要加同步鎖,不然會報上面的錯

synchronized (this) {
this.notifyAll();
}
}



}



(2)

public class testThread {


/**
* @param 主/子線程同步,互斥打印(輪流打印10次,重複5變).............
*/

public static void main(String[] args) {
final Print print = new Print();

new Thread() {
public void run() {
for (int i = 0; i < 5; i++) {
print.printInSubThread(i);


}
};
}.start();
//主線程運行的代碼放在子線程後,不然打印了了一變就成睡眠狀態了,後面的代碼就運行不了
for (int i = 0; i < 5; i++) {
print.printInMainThread(i);
}


}
/////////////////////打印/////////////////////////
public static class Print {
private boolean isPrintMainThread = true;


public synchronized void printInMainThread(int rowNums) {
while (!isPrintMainThread) {
// 子線程在打印,等待
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

for (int i = 0; i < 10; i++) {
System.out.println("printInMainThread" + i + "/" + rowNums);
}
isPrintMainThread = false;
this.notify();

}


public synchronized void printInSubThread(int rowNums) {
while (isPrintMainThread) {
// 主線程在打印,等待
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

for (int i = 0; i < 10; i++) {
System.out.println("printInSubThread:" + i + "/" + rowNums);
}
isPrintMainThread = true;
this.notify();

}
}


}


(3)

如何避免多個線程同時下載同一張圖片(防止併發,要同步)?



final ReentrantLock reentrantLock = new ReentrantLock();
for (int i = 0; i < 10; i++) {
final int j=i;
new Thread(){
public void run() {
reentrantLock.lock();
System.out.println("hello:start:"+j);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("hello:end:"+j);
reentrantLock.unlock();
};
}.start();
}

不同步(這樣就併發了,各做各的事).....................



final ReentrantLock reentrantLock = new ReentrantLock();
for (int i = 0; i < 10; i++) {
final int j=i;
new Thread(){
public void run() {
//reentrantLock.lock();
System.out.println("hello:start:"+j);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("hello:end:"+j);
//reentrantLock.unlock();
};
}.start();
}

(4)

如何避免多個線程同時調用一個方法,導致數據混亂(防止併發,要同步)?

public class testSyn {


/**
* @param args
*/
public static void main(String[] args) {
new Thread(){
public void run() {
while (true) {
go("WUXIFU");

}
};
}.start();
new Thread(){
public void run() {
while (true) {
go("wuyaoping");

}
};
}.start();


}


private static /*synchronized*/void go(String s) {
for (int i = 0; i < s.length(); i++) {
System.out.print(s.charAt(i));


try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}


}
System.out.println();
}


}

結果數據混亂(沒有在方法里加synchronized):



在方法里加synchronized

public class testSyn {


/**
* @param args
*/
public static void main(String[] args) {
new Thread(){
public void run() {
while (true) {
go("WUXIFU");

}
};
}.start();
new Thread(){
public void run() {
while (true) {
go("wuyaoping");

}
};
}.start();


}


private static synchronized void go(String s) {
for (int i = 0; i < s.length(); i++) {
System.out.print(s.charAt(i));


try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}


}
System.out.println();
}


}

結果正常:

(5)如何避免多線程請求同一個接口,只發送一次請求(只請求一次該接口)

package com.example.administrator.myapplication;

import android.util.Log;

import org.junit.Test;

import java.lang.CloneNotSupportedException;
import java.lang.Object;
import java.lang.Override;
import java.lang.System;
import java.util.concurrent.locks.ReentrantLock;

import static org.junit.Assert.*;

/**
 * To work on unit tests, switch the Test Artifact in the Build Variants view.
 */
public class ExampleUnitTest {
    @Test
    public void addition_isCorrect() throws Exception {
        assertEquals(4, 2 + 2);
        test();
       test002();


    }

    private void test() {
        final ReentrantLock reentrantLock = new ReentrantLock();
        for (int i = 0; i < 10; i++) {
            final int position = i;
           new Thread(){
               @Override
               public void run() {
                   super.run();
                   final int position2=position;
                 //  ReentrantLock   reentrantLock2 = new ReentrantLock();
                   new Person(reentrantLock,position).sayHello(new Ihello() {
                       public void goodBye() {
                           System.out.println("成功了" + position2);
                       }
                   });
               }
           }.start();
        }
    }

    private void test002() {
        final ReentrantLock reentrantLock = new ReentrantLock();
        final Person person = new Person(reentrantLock);

        for (int i = 10; i < 20; i++) {
            final int position = i;
            new Thread(){
                @Override
                public void run() {
                    super.run();
                    final int position2=position;
                   person.sayHello(new Ihello() {
                       public void goodBye() {
                           System.out.println("成功了" + position2);
                       }
                   },position2);
                }
            }.start();
        }
    }

    public interface Ihello {
        public void goodBye();
    }

    public class Person {
        private  int position;
        ReentrantLock reentrantLock;

        public Person(ReentrantLock reentrantLock, int position) {
            this.reentrantLock = reentrantLock;
            this.position = position;

        }

        public Person(ReentrantLock reentrantLock) {
            this.reentrantLock = reentrantLock;
        }

        public void sayHello(Ihello ihello) {
                reentrantLock.lock();
            System.out.println("start" + position);
            ihello.goodBye();
            System.out.println("end" + position);
            try {
                //TODO 所有在等待的同樣任務將全部取消
                reentrantLock.lockInterruptibly();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            reentrantLock.unlock();
            System.out.println("結尾" + position);
        }
        public void sayHello(Ihello ihello,int position) {
            reentrantLock.lock();
            System.out.println("start" + position);
            ihello.goodBye();
            System.out.println("end" + position);
            try {
                //TODO 所有在等待的同樣任務將全部取消
                reentrantLock.lockInterruptibly();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("結尾" + position);
            reentrantLock.unlock();
        }

    }


}

返回結果:


java 併發

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章