多線程練習題
編寫程序實現,子線程循環3次,接着主線程循環5次,接着再子線程循環3次,主線程循環5次,如此反復,循環3次
第一種實現方式:使用synchronized關鍵字
package com.aaa.test;
public class Test1 {
private boolean flag=false;
// 主線程要實現的功能
public synchronized void mainFunction(){
while (!flag){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int i=0;i<5;i++){
System.out.println("mainFunction,主線程循環"+i+"次");
}
this.notify();
flag=false;
}
// 子線程要實現的功能
public synchronized void subFunction(){
while (flag){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int i=0;i<3;i++){
System.out.println("subFunction,子線程循環"+i+"次");
}
this.notify();
flag=true;
}
public static void main(String[] args) {
final Test1 t= new Test1();
// 子線程循環三次
new Thread(new Runnable() {
public void run() {
for (int i=0;i<3;i++){
t.subFunction();
System.out.println("======");
}
}
}).start();
// 主線程循環三次
for (int i=0;i<3;i++){
t.mainFunction();
System.out.println("======");
}
}
}
第二種實現方式:使用 lock 鎖和 Condition 接口
package com.aaa.test;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Test2 {
private boolean flag = false;
Lock lock = new ReentrantLock();
Condition con = lock.newCondition();
// 主線程要實現的功能
public void mainFunction(){
System.out.println("1.主線程開始"+" -- flag="+flag);
lock.lock();
try{
while(!flag){
try {
System.out.println("2.主線程等待"+" -- flag="+flag);
con.await();
// 使當前線程加入 await() 等待隊列中,並釋放當鎖,當其他線程調用signal()會重新請求鎖。與Object.wait()類似。
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("7.主線程開始循環5次"+" -- flag="+flag);
for(int i=0;i<5;i++){
System.out.println("mainFunction"+i+" -- flag="+flag);
}
flag = false;
System.out.println("8.喚醒子線程"+" -- flag="+flag);
con.signal();
// 喚醒一個在 await()等待隊列中的線程。與Object.notify()相似
}finally{
lock.unlock();
}
}
// 子線程要實現的功能
public void subFunction(){
System.out.println("3.子線程開始"+" -- flag="+flag);
lock.lock();
try{
while(flag){
try {
System.out.println("6.子線程等待"+" -- flag="+flag);
con.await(); // 使當前線程加入 await() 等待隊列中,並釋放當鎖,當其他線程調用signal()會重新請求鎖。與Object.wait()類似。
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("4.子線程開始循環3次"+" -- flag="+flag);
for(int i=0;i<3;i++){
System.out.println("subFunction"+i+" -- flag="+flag);
}
flag = true;
System.out.println("5.喚醒主線程"+" -- flag="+flag);
con.signal(); // 喚醒一個在 await()等待隊列中的線程。與Object.notify()相似
}finally{
lock.unlock();
}
}
public static void main(String[] args) {
final Test2 t= new Test2();
// 子線程循環三次
new Thread(new Runnable() {
public void run() {
for (int i=0;i<3;i++){
t.subFunction();
System.out.println("======");
}
}
}).start();
// 主線程循環三次
for (int i=0;i<3;i++){
t.mainFunction();
System.out.println("======");
}
}
}
模擬多個人通過一個山洞的模擬,這個山洞每次只能通過一個人,每個人通過山洞的時間為5秒,隨機生成10個人,同時准備過此山洞,顯示以下每次通過山洞的人的姓名。
package com.aaa.test;
import java.util.LinkedHashSet;
import java.util.Set;
public class Test3 implements Runnable{
private static int deng=0;
@Override
public void run() {
deng= deng+50;
try
{
Thread.sleep(deng);
} catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()
+" 過山洞");
}
public static void main(String[] args) {
String ary[] ={"趙","錢","孫","李","周","吳","鄭","王","馮","陳"};
Test3 gsd = new Test3();
Set<Integer> set=new LinkedHashSet<Integer>();
while(true){
if(set.size() == 10){
break;
}
//亂序排列(隨機)
int a=(int) (Math.random()*10);
set.add(a);
}
for(int b:set){
Thread th = new Thread(gsd, ary[b]);
th.start();
}
}
}