本文主要是介绍多线程模拟题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
1. 编写一个程序,启动三个线程,三个线程的 ID 分别是 A,B,C;,每个线程将自己的 ID 值在屏幕上打印 5 遍,打印顺序是 ABCABC…
package test; | |
//编写一个程序,启动三个线程,三个线程的ID分别是A,B,C;,每个线程将自己的ID值在屏幕上打印5遍,打印顺序是ABCABC… | |
public class ABCABCABC { | |
public static int count=0; | |
public static char v ='A'; | |
public synchronized void A(){ | |
for(int i=0;i<5;i++){ | |
while (v!='A'){ | |
try { | |
this.wait(); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
} | |
System.out.println("A"); | |
v='B'; | |
notifyAll(); | |
} | |
} | |
public synchronized void B(){ | |
for(int i=0;i<5;i++){ | |
while (v!='B'){ | |
try { | |
this.wait(); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
} | |
System.out.println("B"); | |
v='C'; | |
notifyAll(); | |
} | |
} | |
public synchronized void C(){ | |
for(int i=0;i<5;i++){ | |
while (v!='C'){ | |
try { | |
this.wait(); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
} | |
System.out.println("C"); | |
v='A'; | |
notifyAll(); | |
} | |
} | |
public static void main(String[] args) { | |
ABCABCABC ab = new ABCABCABC(); | |
new Thread(()->ab.A()).start(); | |
new Thread(()->ab.B()).start(); | |
new Thread(()->ab.C()).start(); | |
} | |
} |
2. 打印 ABC
package test; | |
// 打印ABC | |
public class Main1 { | |
static char v ='A'; | |
public static void main(String[] args) { | |
final Main1 main1 = new Main1(); | |
Thread thread1 = new Thread(() -> main1.A()); | |
Thread thread2 = new Thread(() -> main1.B()); | |
Thread thread3= new Thread(() -> main1.C()); | |
thread1.start(); | |
thread2.start(); | |
thread3.start(); | |
} | |
private synchronized void A() { | |
while (true){ | |
if(v == 'A'){ | |
System.out.println('A'); | |
v = 'B'; | |
this.notifyAll(); | |
}else{ | |
try { | |
this.wait(); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
} | |
} | |
} | |
private synchronized void B() { | |
while (true){ | |
if(v == 'B'){ | |
System.out.println('B'); | |
v = 'C'; | |
this.notifyAll(); | |
}else{ | |
try { | |
this.wait(); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
} | |
} | |
} | |
private synchronized void C() { | |
while (true){ | |
if(v == 'C'){ | |
System.out.println('C'); | |
v = 'A'; | |
this.notifyAll(); | |
}else{ | |
try { | |
this.wait(); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
} | |
} | |
} | |
} |
3. 两个线程轮流打印数字,一直到 100
package test; | |
/** | |
* 两个线程轮流打印数字,一直到100 | |
* | |
* Java的wait()、notify()学习: | |
* https://blog.csdn.net/boling_cavalry/article/details/77995069 | |
*/ | |
public class TakeTurnsPrint { | |
public static class TakeTurns { | |
private static boolean flag = true; | |
private static int count = 0; | |
public synchronized void print1() { | |
for (int i = 1; i <= 50; i++) { | |
while (!flag) { | |
try { | |
System.out.println("print1: wait before"); | |
wait(); | |
System.out.println("print1: wait after"); | |
} catch (InterruptedException e) { | |
} | |
} | |
System.out.println("print1: " + ++count); | |
flag = !flag; | |
notifyAll(); | |
} | |
} | |
public synchronized void print2() { | |
for (int i = 1; i <= 50; i++) { | |
while (flag) { | |
try { | |
System.out.println("print2: wait before"); | |
wait(); | |
System.out.println("print2: wait after"); | |
} catch (InterruptedException e) { | |
} | |
} | |
System.out.println("print2: " + ++count); | |
flag = !flag; | |
notifyAll(); | |
} | |
} | |
} | |
public static void main(String[] args){ | |
TakeTurns takeTurns = new TakeTurns(); | |
new Thread(()->takeTurns.print1()).start(); | |
new Thread(()->takeTurns.print2()).start(); | |
} | |
} |
4. 写两个线程,一个线程打印 1~ 52,另一个线程打印 A~Z,打印顺序是 12A34B…5152Z
package test; | |
public class TakeTurnsPrint2 { | |
private boolean flag = true; // 初始化flag状态,确保第一个线程开始执行 | |
private int count = 1; // 从1开始计数 | |
public synchronized void printNum() { | |
for (int i = 0; i < 26; i++) { | |
while (!flag) { // 等待切换到数字打印 | |
try { | |
wait(); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
} | |
System.out.print(count++); System.out.print(count++); | |
flag = !flag; // 切换标志 | |
notifyAll(); // 唤醒其他等待的线程 | |
} | |
} | |
public synchronized void printLetter() { | |
for (char ch = 'A'; ch <= 'Z'; ch++) { // 直接使用char遍历字母表 | |
while (flag) { // 等待切换到字母打印 | |
try { | |
wait(); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
} | |
System.out.println(ch); | |
flag = !flag; // 切换标志 | |
notifyAll(); // 唤醒其他等待的线程 | |
} | |
} | |
public static void main(String[] args) { | |
TakeTurnsPrint2 takeTurnsPrint2 = new TakeTurnsPrint2(); | |
new Thread(takeTurnsPrint2::printNum).start(); | |
new Thread(takeTurnsPrint2::printLetter).start(); | |
} | |
} |
5. 编写 10 个线程,第一个线程从 1 加到 10,第二个线程从 11 加 20… 第十个线程从 91 加到 100,最后再把 10 个线程结果相加。
package test; | |
//编写10个线程,第一个线程从1加到10,第二个线程从11加20…第十个线程从91加到100,最后再把10个线程结果相加。 | |
public class TenThreadSum { | |
public static class SumThread extends Thread{ | |
int forct = 0; int sum = 0; | |
SumThread(int forct){ | |
this.forct = forct; | |
} | |
@Override | |
public void run() { | |
for(int i = 1; i <= 10; i++){ | |
sum += i + forct * 10; | |
} | |
System.out.println(getName() + " " + sum); | |
} | |
} | |
public static void main(String[] args) { | |
int result = 0; | |
for(int i = 0; i < 10; i++){ | |
SumThread sumThread = new SumThread(i); | |
sumThread.start(); | |
try { | |
sumThread.join(); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
//join()方法被用来确保每个SumThread线程执行完毕并计算出自己的求和结果之后,主线程再收集这些结果进行最终的总和计算 | |
result = result + sumThread.sum; | |
} | |
System.out.println("result " + result); | |
} | |
} |
6. 创建四个线程,2 个增加,2 个删除,保证数据合法
package test; | |
public class Test1 { | |
private int j ;//变量j | |
public static void main(String[] args) { | |
Test1 t=new Test1(); | |
Add add=t.new Add();//内部类的实例 | |
Sub sub=t.new Sub(); | |
for(int i=0;i<2;i++){//循环两边创建四个线程,两加两减 | |
Thread t1=new Thread(add); | |
t1.start(); | |
Thread t2=new Thread(sub); | |
t2.start(); | |
} | |
} | |
private synchronized void add(){ | |
j++; | |
System.out.println(Thread.currentThread().getName()+":"+j); | |
} | |
private synchronized void sub(){ | |
j--; | |
System.out.println(Thread.currentThread().getName()+":"+j); | |
} | |
class Add extends Thread{ | |
@Override | |
public void run() { | |
for(int i=0;i<10;i++){ | |
add(); | |
} | |
} | |
} | |
class Sub extends Thread{ | |
@Override | |
public void run() { | |
for (int i=0;i<10;i++){ | |
sub(); | |
} | |
} | |
} | |
} |
7. 三个窗口同时买票
package test; | |
/** | |
* 三个窗口同时卖票 | |
*/ | |
/** | |
* 票 | |
*/ | |
class Ticket { | |
private int count = 1; | |
public void sale() { | |
while (true) { | |
synchronized (this) { | |
if (count > 200) { | |
System.out.println("票已经卖完啦"); | |
break; | |
} else { | |
System.out.println(Thread.currentThread().getName() + "卖的第 " + count++ + " 张票"); | |
} | |
try { | |
Thread.sleep(200); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
} | |
} | |
} | |
} | |
/** | |
* 售票窗口 | |
*/ | |
class SaleWindows extends Thread { | |
private Ticket ticket; | |
public SaleWindows(String name, Ticket ticket) { | |
super(name); | |
this.ticket = ticket; | |
} | |
@Override | |
public void run() { | |
super.run(); | |
ticket.sale(); | |
} | |
} | |
public class TicketDemo { | |
public static void main(String[] args) { | |
Ticket ticket = new Ticket(); | |
SaleWindows windows1 = new SaleWindows("窗口1", ticket); | |
SaleWindows windows2 = new SaleWindows("窗口2", ticket); | |
SaleWindows windows3 = new SaleWindows("窗口3", ticket); | |
windows1.start(); | |
windows2.start(); | |
windows3.start(); | |
} | |
} |
8. 交替打印两个数组
package test; | |
//交替打印两个数组 | |
public class TwoArr { | |
int []arr1 = new int[]{1,3,5,7,9}; | |
int []arr2 = new int[]{2,4,6,8,10}; | |
public static boolean flag = false; | |
public synchronized void printArr1(){ | |
for(int i=0;i<arr1.length;i++){ | |
while (flag){ | |
try { | |
this.wait(); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
} | |
System.out.println(arr1[i]); | |
flag=!flag; | |
notifyAll(); | |
} | |
} | |
public synchronized void printArr2(){ | |
for(int i=0;i<arr2.length;i++){ | |
while (!flag){ | |
try { | |
this.wait(); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
} | |
System.out.println(arr2[i]); | |
flag=!flag; | |
notifyAll(); | |
} | |
} | |
public static void main(String[] args) { | |
TwoArr twoArr = new TwoArr(); | |
new Thread(()->twoArr.printArr1()).start(); | |
new Thread(()->twoArr.printArr2()).start(); | |
} | |
} |
9. 猴子抢桃子多线程(多窗口变形)
//3只猴子抢着分100只桃子,每只抢到的猴子分去剩余桃子的一半。使用多线程模拟这一过程 | |
public class Monet { | |
static class Peach{ | |
int value = 100; | |
int temp = 0; | |
public void get(){ | |
while (true){ | |
temp = value; | |
synchronized (this){ | |
if(temp>0){ | |
if(temp%2==0){ | |
value = temp/2; | |
}else{ | |
value = temp-(temp+1)/2; | |
} | |
System.out.println(Thread.currentThread().getName() + " 抢到了 " + (temp - value) + " 个桃子,还剩 "+ | |
value); | |
try { | |
Thread.sleep(500); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
}else{ | |
System.out.println("桃子已经无了"); | |
break; | |
} | |
} | |
} | |
} | |
} | |
static class Monkey extends Thread{ | |
Peach peach; | |
public Monkey(String name, Peach peach) { | |
super(name); | |
this.peach = peach; | |
} | |
@Override | |
public void run() { | |
super.run(); | |
peach.get(); | |
} | |
} | |
public static void main(String[] args) { | |
Peach peach = new Peach(); | |
Monkey m1 = new Monkey("猴子1", peach); | |
Monkey m2 = new Monkey("猴子2", peach); | |
Monkey m3 = new Monkey("猴子3", peach); | |
m1.start(); | |
m2.start(); | |
m3.start(); | |
} | |
} |
10. 总结
首先做这个题目,就俩种形式,一种是顺序打印,就只有学会 wait (),notify (),notifyAll (), 然后,你要等线程做完了,才获取下一步则使用 Join(),然后关于多窗口卖票和猴子抢桃子,实际上是一种题目的变形,我只要保证 ticket 和 peach 是同一个对象,我就可以操作他们,以及怎么保持数据一致性,就使用 synchronized 解决
这篇关于多线程模拟题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!