实现Runnsble
需要调用start方法,所以需要创建一个代理类对象
package com.sxt.thread;
/**
* 创建线程方式er:
* 1、创建:继承Runnable+重写run
* 2、启动:创建实现类对象+Thread对象+start
*/
public class StartRun implements Runnable{
/**
* 线程的入口点
*/
@Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println("一边coding");
}
}
public static void main(String[] args) {
// //创建实现类对象
// StartRun sr = new StartRun();
// //创建代理类对象 调用子类的start方法启动
// new Thread(sr).start();
new Thread(new StartRun()).start();//对象只用一次 可以使用匿名
//st.run();//普通方法的调用
for (int i = 0; i <20 ; i++) {
System.out.println("一边听歌");
}
}
}
推荐使用:避免单继承的局限性,优先使用接口
方便资源共享
package com.sxt.thread;
public class lDownloader implements Runnable {
private String url;//远程路径
private String name;//存储名字
public lDownloader(String name, String url) {
this.url = url;
this.name = name;
}
@Override
public void run() {
WebDownloader wd=new WebDownloader();
wd.download(url,name);
}
public static void main(String[] args) {
lDownloader td1 = new lDownloader("phone.jpg"," http://upload.news.cecb2b.com/2014/0511/1399775432250.jpg");
lDownloader td2 = new lDownloader("spl.jpg","http://p1.pstatp.com/large/403c00037462ae2eee13");
lDownloader td3 = new lDownloader("success.jpg","http://5b0988e595225.cdn.sohucs.com/images/20170830/d8b57e0dce0d4fa29bd5ef014be663d5.jpeg");
//启动三个线程
new Thread(td1).start();
new Thread(td2).start();
new Thread(td3).start();
}
}
/**
package com.sxt.thread;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
/**
* 下载图片
*/
public class WebDownloader {
/**
* 下载
* @param url
* @param name
*/
public void download(String url, String name) {
try {
FileUtils.copyURLToFile(new URL(url), new File(name));
} catch (MalformedURLException e) {
e.printStackTrace();
System.out.println("不合法的url");
} catch (IOException e) {
e.printStackTrace();
System.out.println("下载失败");
}
}
}
*/
12306抢票的问题
多线程共享资源
但事实上存在延迟多并发的问题 这时候线程安全就很重要
package com.sxt.thread;
/**
* 共享资源 并发(线程安全)
*/
public class Web12306 implements Runnable{
//票数
private int ticketNums=99;
@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) {
//一份资源
Web12306 web = new Web12306();
//多个代理
new Thread(web,"马畜").start();
new Thread(web,"码农").start();
new Thread(web,"蚂蟥").start();
}
}
模拟龟兔赛跑
判断是否有胜利者了
没有胜利者时达到了100步就胜利了
判断比赛是否结束
我们可以获取到兔子的名字时它每走十步休息0.8毫秒
package com.sxt.thread;
/**
* 模拟龟兔赛跑
*/
public class Racer implements Runnable {
private String winner;//胜利者
@Override
public void run() {
for (int steps = 1; steps <= 100; steps++) {
//模拟休息
if (Thread.currentThread().getName().equals("兔子")&&steps%10==0){
try {
Thread.sleep((long) 0.8);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + "--->" + steps);
//比赛是否结束
boolean flg=gameWinner(steps);
if (flg){
break;
}
}
}
private boolean gameWinner(int steps) {
if (winner != null) {//存在胜利者
return true;
} else {
if (steps == 100) {
winner=Thread.currentThread().getName();
System.out.println("winner=="+winner);
return true;
}
}
return false;
}
public static void main(String[] args) {
Racer racer = new Racer();
new Thread(racer,"乌龟").start();
new Thread(racer,"兔子").start();
}
}
实现Callable接口
了解下就好
并发领域
- 创建目标对象
- 创建执行服务
- 提交执行
- 获取结果
- 关闭服务
可以扔出异常,Runnable方法不可以,返回值是可以进行返回的,Runnable里不能返回,是void
创建执行服务:
ExecutorService ser= Executors.newFixedThreadPool(3);
提交执行:
Future result1=ser.submit(td1);
获取结果:
boolean r1=result1.get(r1);
System.out.println(r1);
关闭服务:
ser.shutdownNow();
package com.sxt.thread;
import java.util.concurrent.*;
/**
* 了解创建线程的方式三:Callable接口
*/
public class CDownloader implements Callable<Boolean> {
private String url;//远程路径
private String name;//存储名字
public CDownloader(String name, String url) {
this.url = url;
this.name = name;
}
@Override
public Boolean call() throws Exception{
WebDownloader wd=new WebDownloader();
wd.download(url,name);
System.out.println(name);
return true;
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
CDownloader td1 = new CDownloader("phone.jpg"," http://upload.news.cecb2b.com/2014/0511/1399775432250.jpg");
CDownloader td2 = new CDownloader("spl.jpg","http://p1.pstatp.com/large/403c00037462ae2eee13");
CDownloader td3 = new CDownloader("success.jpg","http://5b0988e595225.cdn.sohucs.com/images/20170830/d8b57e0dce0d4fa29bd5ef014be663d5.jpeg");
//创建执行服务
ExecutorService ser= Executors.newFixedThreadPool(3);
//提交执行
Future<Boolean> result1=ser.submit(td1);
Future<Boolean> result2=ser.submit(td2);
Future<Boolean> result3=ser.submit(td3);
//获取结果
boolean r1=result1.get();
boolean r2=result1.get();
boolean r3=result1.get();
System.out.println(r3);
//关闭服务
ser.shutdownNow();
}
}
利用Callable接口实现龟兔赛跑
package com.sxt.thread;
import java.util.concurrent.*;
/**
* 模拟龟兔赛跑
*/
public class CollableRacer implements Callable<Integer> {
private String winner;//胜利者
@Override
public Integer call()throws Exception {
for (int steps = 1; steps <= 100; steps++) {
//模拟休息
if (Thread.currentThread().getName().equals("pool-1-thread-1") && steps % 10 == 0) {
Thread.sleep(100);
}
System.out.println(Thread.currentThread().getName() + "--->" + steps);
//比赛是否结束
boolean flg = gameWinner(steps);
if (flg) {
return steps;
}
}
return null;
}
private boolean gameWinner(int steps) {
if (winner != null) {//存在胜利者
return true;
} else {
if (steps == 100) {
winner = Thread.currentThread().getName();
System.out.println("winner==" + winner);
return true;
}
}
return false;
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
CollableRacer racer = new CollableRacer();
//创建执行服务
ExecutorService ser= Executors.newFixedThreadPool(2);
//提交执行
Future<Integer> result1=ser.submit(racer);
Future<Integer> result2=ser.submit(racer);
//获取结果
Integer r1=result1.get();
Integer r2=result2.get();
System.out.println(r1+"--->"+r2);
//关闭服务
ser.shutdownNow();
}
}