<>线程创建

<>方法一:继承Thread类

<>步骤

* 自定义线程类继承Thread类
* 重写run()方法,编写线程执行体
* 创建线程对象,调用start()方法启动线程
注意:线程 不一定立即执行,CPU安排调度
//创建线程方式一:继承Thread类,重写run()方法,调用start开启线程 //线程开启不一定立即执行,由CPU调度执行 public class
TestThread1 extends Thread/*继承Thread类*/{ @Override public void run() {
/*重写run()方法*/ for (int i = 1; i <=200; i++) { System.out.println("我在看代码---"+i);
} } public static void main(String[] args) { TestThread1 testThread1 = new
TestThread1(); testThread1.start();/*调用start开启线程*/ for (int i = 1; i < 200; i++)
{//主线程main方法里也执行循环语句进行参照 System.out.println("我在学习多线程---"+i); } } } /* 输出结果:交替输出
我在学习多线程---1 我在看代码---1 我在看代码---2 我在看代码---3 我在学习多线程---2 我在看代码---4 我在学习多线程---3
我在看代码---5 我在学习多线程---4 我在看代码---6 我在学习多线程---5 我在看代码---7 我在学习多线程---6 我在看代码---8
我在学习多线程---7 我在看代码---9 我在学习多线程---8 我在看代码---10 我在学习多线程---9 ...... */
<>案例:下载图片
//练习Thread,实现多线程同步下载图片 public class TestThread2 extends Thread{ private String
url;//网络图片地址 private String fileName;//保存的文件名 public TestThread2(String url,
String fileName) { this.url = url; this.fileName = fileName; } @Override public
void run() { WebDownloader webDownloader = new WebDownloader(); webDownloader.
downloader(url,fileName); System.out.println("下载了文件名为:"+fileName); } public
static void main(String[] args) { TestThread2 t1 = new TestThread2("图片1路径",
"1.jpg"); TestThread2 t2 = new TestThread2("图片2路径", "2.jpg"); TestThread2 t3 =
new TestThread2("图片3路径", "3.jpg"); //先下载t1 t1.start(); //然后是t2 t2.start();
//最后是t3 t3.start(); /* 实际顺序: 下载了文件名为:2.jpg 下载了文件名为:1.jpg 下载了文件名为:3.jpg */
//所以,三张图片下载其实是同时进行 } } //下载器 class WebDownloader extends Thread{ //下载方法 public
void downloader(String url,String fileName){ try { FileUtils.copyURLToFile(new
URL(url),new File(fileName)); } catch (IOException e) { e.printStackTrace();
System.out.println("IO异常,downloader方法出现问题。"); } } }
<>图片欣赏~

<>方法二:实现Runnable接口

<>步骤

* 定义MyRunnable类实现Runnable接口
* 实现run()方法,编写线程执行体
* 创建Thread类代理对象,调用start()方法 //创建线程方式二:实现Runnable接口 public class TestThread3
implements Runnable{ @Override public void run() { for (int i = 1; i <=200; i++)
{ System.out.println("我在看代码---"+i); } } public static void main(String[] args) {
TestThread3 testThread3= new TestThread3(); //
testThread3.start();实现Runnable接口的类没有start()方法,所以要借助Thread类代理 new Thread(
testThread3).start(); for (int i = 1; i < 200; i++) { System.out.println(
"我在学习多线程---"+i); } } } //运行结果 /* 我在学习多线程---1 我在看代码---1 我在学习多线程---2 我在看代码---2
我在学习多线程---3 我在看代码---3 我在学习多线程---4 我在看代码---4 我在学习多线程---5 我在看代码---5 我在学习多线程---6
我在看代码---6 我在学习多线程---7 我在看代码---7 我在学习多线程---8 */
<>对比两种方法

*
继承Thread类

* 子类继承Thread类,具备多线程能力
* 启动线程:子类对象.start()
* 不建议使用:避免OOP单继承的局限性
*
实现Runnable接口

* 实现接口Runnable,具备多线程能力
* 启动线程:传入目标对象+Thread代理对象.start()
* 推荐使用:能够避免单继承的局限性 ,灵活方便,可以让同一个对象被多个线程使用
<>初识并发问题
//抢票问题 public class TestThread4 implements Runnable{ private int ticketNum=10;
@Override public void run() { while (true){ if (ticketNum<=0)break; try { Thread
.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } System.
out.println(Thread.currentThread().getName()+"抢到了第"+ticketNum--+"张票"); } }
public static void main(String[] args) { TestThread4 ticket = new TestThread4();
new Thread(ticket,"Jack").start(); new Thread(ticket,"Teacher").start(); new
Thread(ticket,"YellowBull").start(); } } /* Teacher抢到了第8张票 Jack抢到了第9张票
YellowBull抢到了第10张票 Jack抢到了第6张票 YellowBull抢到了第7张票 Teacher抢到了第6张票
YellowBull抢到了第5张票 Teacher抢到了第5张票 Jack抢到了第4张票 Teacher抢到了第3张票 Jack抢到了第1张票
YellowBull抢到了第2张票 这里出现了一张票被抢两次的情况,这是并发的问题 */
多个线程同时操作同一资源的情况下,线程不安全,会发生数据紊乱

<>案例:龟兔赛跑
//模拟龟兔赛跑 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(); } } boolean
flag= gameOver(i);//判断比赛是否结束 if (flag)break; System.out.println(Thread.
currentThread().getName()+"跑了"+i+"步"); } } //判断比赛结束,谁是胜利者 public boolean
gameOver(int steps){ if (winner!=null){ return true; }{ if (steps>=100){ winner
= Thread.currentThread().getName(); System.out.println(winner +"是胜利者"); return
true; }} return false; } public static void main(String[] args) { Race race =
new Race(); new Thread(race,"兔子").start(); new Thread(race,"乌龟").start(); } }
<>方法三:实现Callable方法(了解即可)

<>步骤

* 实现Callable接口,需要返回值类型
* 重写call()方法,需要抛出异常
* 创建目标对象
* 创建执行服务
* 提交执行
* 获取结果
* 关闭服务 //线程创建方式三:实现Callable接口 /* callable的好处 1.可以定义返回值 2.可以抛出异常 */ public
class TestCallable implements Callable<Boolean> { private String url;//网络图片地址
private String fileName;//保存的文件名 public TestCallable(String url, String fileName
) { this.url = url; this.fileName = fileName; } @Override public Boolean call()
{ WebDownloader webDownloader = new WebDownloader(); webDownloader.downloader(
url,fileName); System.out.println("下载了文件名为:"+fileName); return true; } public
static void main(String[] args) throws ExecutionException, InterruptedException
{ TestCallable t1 = new TestCallable("略","1.jpg"); TestCallable t2 = new
TestCallable("略","2.jpg"); TestCallable t3 = new TestCallable("略","3.jpg");
//四步:创建执行服务——>提交执行——>获取结果——>关闭服务 //创建执行服务 ExecutorService executorService =
Executors.newFixedThreadPool(3); //提交执行 Future<Boolean> r1 = executorService.
submit(t1); Future<Boolean> r2 = executorService.submit(t2); Future<Boolean> r3
= executorService.submit(t3); //获取结果 Boolean rs1 = r1.get(); Boolean rs2 = r2.
get(); Boolean rs3 = r3.get(); System.out.println(rs1); System.out.println(rs2);
System.out.println(rs3); //关闭服务 executorService.shutdownNow(); } } //下载器 class
WebDownloader extends Thread{ //下载方法 public void downloader(String url,String
fileName){ try { FileUtils.copyURLToFile(new URL(url),new File(fileName)); }
catch (IOException e) { e.printStackTrace(); System.out.println(
"IO异常,downloader方法出现问题。"); } } }

技术
下载桌面版
GitHub
Gitee
SourceForge
百度网盘(提取码:draw)
云服务器优惠
华为云优惠券
腾讯云优惠券
阿里云优惠券
Vultr优惠券
站点信息
问题反馈
邮箱:[email protected]
吐槽一下
QQ群:766591547
关注微信