前言
前面的二、三篇我们学习了继承Thread类以及实现Runnable接口的两种方式来实现多线程,那么本篇我们将学习在多线程过程中出现的并发问题。
一、并发问题
多个进程或线程同时(或者说在同一段时间内)访问同一资源会产生并发问题。
二、代码示例
1.买票产生的并发问题
代码如下(示例):
//多个线程处理一个资源问题,车票问题。
//问题:多个线程同时操作一个资源,线程不安全,数据紊乱。
public class TestThread05 implements Runnable {
private int ticketNums = 10;
@Override
public void run() {
while (true){
if(ticketNums <= 0){
break;
}
try {
Thread.sleep(200);
}catch (InterruptedException e){
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"-->拿到了第"+ticketNums-- +"票");
}
}
public static void main(String[] args) {
TestThread05 ticket = new TestThread05();
new Thread(ticket,"小明").start();
new Thread(ticket,"老师").start();
new Thread(ticket,"黄牛").start();
}
}
运行结果:
2.龟兔赛跑实例
代码如下(示例):
public class Race implements Runnable{
private static String winner;
@Override
public void run() {
for(int i=1;i<=100;i++){
//模拟兔子休息
if(Thread.currentThread().getName().equals("兔子")){
i = i + 5;
if(i%30==0) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//判断比赛是否结束
boolean flag = gameOver(i);
if(flag){
break;
}
System.out.println(Thread.currentThread().getName()+"-->跑了"+i+"步");
}
}
//判断是否完成比赛
public boolean gameOver(int steps){
//判断是否有胜利者
if (winner!=null){
return true;
}else {
if(steps>=100){
winner=Thread.currentThread().getName();
System.out.println("Winner is"+winner);
return true;
}
}
return false;
}
public static void main(String[] args) {
Race race = new Race();
new Thread(race,"乌龟").start();
new Thread(race,"兔子").start();
}
}
运行结果:
总结
本篇我们学习了并发问题的产生,关于并发问题的解决我们留到之后解决。