06 初识并发问题——以购买火车票为例
package threadLearn.demo01;
public class TestThread4 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) {
TestThread4 ticket = new TestThread4();
new Thread(ticket,"小明").start();
new Thread(ticket,"老师").start();
new Thread(ticket,"黄牛").start();
System.out.println(Thread.currentThread().getName());
}
}
输出:
黄牛--->拿到了第10票
老师--->拿到了第10票
小明--->拿到了第9票
老师--->拿到了第8票
黄牛--->拿到了第7票
小明--->拿到了第8票
小明--->拿到了第5票
黄牛--->拿到了第4票
老师--->拿到了第6票
小明--->拿到了第2票
黄牛--->拿到了第1票
老师--->拿到了第3票
从中我们可以看到问题:多个线程操作同一个资源的时候,容易出现并发问题,同一个资源被不同的线程访问
07 龟兔赛跑
package threadLearn.demo01;
public class Race implements Runnable{
private static String winner;
@Override
public void run() {
for (int i = 0; i <= 100; i++) {
if (Thread.currentThread().getName().equals("兔子") && i%10==0){
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//判断比赛是否结束
//如果比赛结束了,就停止程序
if (gameOver(i)){
break;
}
System.out.println(Thread.currentThread().getName() + "-->跑了" + i + "步");
}
}
private boolean gameOver(int steps){
//判断是否有胜利者
if (winner!=null){
return true;
}{
if (steps>=100){
winner =Thread.currentThread().getName();
System.out.println("winner is "+winner);
return true;
}
}
return false;
}
public Race() {
}
public static void main(String[] args) {
Race race = new Race();
new Thread(race,"兔子").start();
new Thread(race,"乌龟").start();
}
}
08 实现Callable接口
package threadLearn.demo02;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.*;
public class TestCallable implements Callable<Boolean> {
private String url;
private String name;
public TestCallable(String url, String name) {
this.url = url;
this.name = name;
}
@Override
public Boolean call() throws Exception {
WebDownloader webDownloader = new WebDownloader();
webDownloader.downloader(url,name);
System.out.println("下载了文件名为:"+name);
return true;
}
public static void main(String[] args) {
TestCallable t1 = new TestCallable("https://n.sinaimg.cn/news/transform/350/w210h140/20210713/a5f2-b6ea01a4a9952832066c1bc25dfa04e7.jpg","20210713_11.jpg");
TestCallable t2 = new TestCallable("https://n.sinaimg.cn/news/transform/350/w210h140/20210713/64a8-8bf9fb26cdea87a38a446e5c1c685c4c.jpg","20210713_22.jpg");
TestCallable t3 = new TestCallable("https://n.sinaimg.cn/ent/transform/175/w105h70/20210713/4047-3aee4bc841cadc336b7104473218c732.jpg","20210713_33.jpg");
//创建执行服务:
//提交执行
ExecutorService executorService = Executors.newFixedThreadPool(1);
//获取结果
Future<Boolean> r1 = executorService.submit(t1);
Future<Boolean> r2 = executorService.submit(t2);
Future<Boolean> r3 = executorService.submit(t3);
//获取结果
try {
Boolean rs1 = r1.get();
Boolean rs2 = r2.get();
Boolean rs3 = r3.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
//关闭服务
executorService.shutdownNow();
}
}
class WebDownloader{
public void downloader(String url, String name){
try{
FileUtils.copyURLToFile(new URL(url),new File(name));
}catch (IOException e){
e.printStackTrace();
System.out.println("IO异常,downloader方法出现问题");
}
}
}