第1關:并發編程的三個概念
任務描述
在我們進行應用開發的時候,常常會關注網站的并發,如果網站的用戶量很多,當這些用戶同時訪問一個服務的時候,我們的服務器就會接收到大量的并發請求,處理好這些并發請求是一個合格程式員必須要完成的作業,
理解并發編程的三個概念對于我們更好的開發高并發的Web應用有很大的幫助,
本關的任務就是理解并發編程的三個重要概念并完成右側選擇題,
-
1、在并發編程中,我們需要以下哪幾個特性來保持多執行緒程式執行正確(ABD )
A、可見性
B、原子性
C、并發性
D、有序性 -
2、請分析以下陳述句哪些是原子操作(AB )
A、int a = 3;
B、boolean flag = false;
C、a–;
D、a =a *a -
3、以下代碼的執行結果是(E)
public class Test {public int inc = 0;public void increase() {inc++;}public static void main(String[] args) {final Test test = new Test();for(int i=0;i<10;i++){new Thread(){public void run() {for(int j=0;j<1000;j++)test.increase();};}.start();}while(Thread.activeCount()>1) //保證前面的執行緒都執行完Thread.yield();System.out.println(test.inc);}}
B、9870
C、大于10000
D、小于10000
E、不一定,大概率小于一萬
第2關:使用synchronized關鍵字同步執行緒
任務描述
本關任務:使右側代碼中的insert方法在同一時刻只有一個執行緒能訪問,
編程要求
請仔細閱讀右側代碼,根據方法內的提示,在Begin - End區域內進行代碼補充,具體任務如下:
- 使
num變數在同一時刻只能有一個執行緒可以訪問,
測驗說明
使程式的輸出結果如下:

通關代碼
package step2;
public class Task {
public static void main(String[] args) {
final insertData insert = new insertData();
for (int i = 0; i < 3; i++) {
new Thread(new Runnable() {
public void run() {
insert.insert(Thread.currentThread());
}
}).start();
}
}
}
class insertData{
public static int num =0;
/********* Begin *********/
public synchronized void insert(Thread thread){
for (int i = 0; i <= 5; i++) {
num++;
System.out.println(num);
}
}
/********* End *********/
}
第3關:使用執行緒鎖(Lock)實作執行緒同步
任務描述
本關任務:使用Lock,實作對于某一塊代碼的互斥訪問
編程要求
請仔細閱讀右側代碼,根據方法內的提示,在Begin - End區域內進行代碼補充, ####測驗說明
使得程式輸出如下結果(因為執行緒的執行順序是隨機的可能需要你評測多次):

通關代碼
package step3;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Task {
public static void main(String[] args) {
final Insert insert = new Insert();
Thread t1 = new Thread(new Runnable() {
public void run() {
insert.insert(Thread.currentThread());
}
});
Thread t2 = new Thread(new Runnable() {
public void run() {
insert.insert(Thread.currentThread());
}
});
Thread t3 = new Thread(new Runnable() {
public void run() {
insert.insert(Thread.currentThread());
}
});
// 設定執行緒優先級
t1.setPriority(Thread.MAX_PRIORITY);
t2.setPriority(Thread.NORM_PRIORITY);
t3.setPriority(Thread.MIN_PRIORITY);
t1.start();
t2.start();
t3.start();
}
}
class Insert {
public static int num;
// 在這里定義Lock
private Lock lock = new ReentrantLock();
public void insert(Thread thread) {
/********* Begin *********/
if(lock.tryLock()){
try{
System.out.println(thread.getName()+"得到了鎖");
for (int i = 0; i < 5; i++) {
num++;
System.out.println(num);
}
}finally{
System.out.println(thread.getName()+"釋放了鎖");
lock.unlock();
}
}else{
System.out.println(thread.getName()+"獲取鎖失敗");
}
}
/********* End *********/
}
在這種情況之下,程式輸出所需要的結果可能需要多次,因為執行緒的執行順序是隨機的,我們可以通過sleep()方法來改行程式,這樣就不需要設定線程優先級,
通關代碼(改進)
package step3;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Task {
public static void main(String[] args) throws InterruptedException {
final Insert insert = new Insert();
Thread t1 = new Thread(new Runnable() {
public void run() {
insert.insert(Thread.currentThread());
}
});
Thread t2 = new Thread(new Runnable() {
public void run() {
insert.insert(Thread.currentThread());
}
});
Thread t3 = new Thread(new Runnable() {
public void run() {
insert.insert(Thread.currentThread());
}
});
// 設定執行緒優先級
/*
t1.setPriority(Thread.MAX_PRIORITY);
t2.setPriority(Thread.NORM_PRIORITY);
t3.setPriority(Thread.MIN_PRIORITY);
t1.start();
t2.start();
t3.start();
*/
t1.start();
t2.sleep(500);
t2.start();
t3.sleep(1000);
t3.start();
}
}
class Insert {
public static int num;
// 在這里定義Lock
private Lock lock = new ReentrantLock();
public void insert(Thread thread) {
/********* Begin *********/
if (lock.tryLock()) {
try {
System.out.println(thread.getName() + "得到了鎖");
for (int i = 0; i < 5; i++) {
num++;
System.out.println(num);
}
} finally {
System.out.println(thread.getName() + "釋放了鎖");
lock.unlock();
}
} else {
System.out.println(thread.getName() + "獲取鎖失敗");
}
}
/********* End *********/
}
第4關:使用volatile實作變數的可見性
任務描述
本關任務:使用volatile關鍵字與同步實作右側程式輸出10000,
編程要求
請仔細閱讀右側代碼,根據方法內的提示,在Begin - End區域內進行代碼補充, ####測驗說明
預期輸出:10000,
提示:可以使用兩種方式實作原子性,所以本關有多種方式都可以通關,
通關代碼
package step4;
public class Task {
public volatile int inc = 0;
//請在此添加實作代碼
/********** Begin **********/
public synchronized void increase() {
inc++;
}
/********** End **********/
public static void main(String[] args) {
final Task test = new Task();
for (int i = 0; i < 10; i++) {
new Thread() {
public void run() {
for (int j = 0; j < 1000; j++)
test.increase();
};
}.start();
}
while (Thread.activeCount() > 1) // 保證前面的執行緒都執行完
Thread.yield();
System.out.println(test.inc);
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/267480.html
標籤:其他
