线程
继承Thread类
package com.teatea.demo01;
//创建线程方程一:继承Threa类,重写run方法,调用start开启线程
public class TestThread1 extends Thread{
@Override
public void run() {
//run方法线程体
for (int i = 0; i < 20; i++) {
System.out.println("我在看代码---"+i);
}
}
public static void main(String[] args) {
//main方法,主线程
//创建一个线程对象
TestThread1 testThread1 = new TestThread1();
//调用start()方法开启线程
testThread1.start();
for (int i = 0; i < 20; i++) {
System.out.println("我在学习多线程---"+i);
}
}
}
实例—网图下载代码
package com.teatea.demo01;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.net.URL;
//练习Thread,实现多线程同步下载图片
//2.继承类,编写构造方法
public class TestThread2 extends Thread{
private String url;
private String name;
public TestThread2(String url,String name){
this.url = url; //文件下载地址
this.name = name; //保存文件名
}
//下载图片线程的执行体
//3.重写run方法
@Override
public void run() {
WebDownloader webDownloader = new WebDownloader();
webDownloader.downloader(url,name);
System.out.println("下载了文件名为"+name+"的文件");
}
//4.线程启动
public static void main(String[] args) {
TestThread2 testThread2 = new TestThread2("https://pic1.zhimg.com/v2-7c168a484333f45b2315c9d1afa13d74_r.jpg?source=1940ef5c","图片2");
TestThread2 testThread3 = new TestThread2("https://pic1.zhimg.com/v2-7c168a484333f45b2315c9d1afa13d74_r.jpg?source=1940ef5c","图片3");
testThread2.start();
testThread3.start();
}
}
//1.下载器
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方法出现问题");
}
}
}
/*
1.写一个下载器,里面有下载方法
2.实现一个线程类,用TestThread2继承Thread类
用构造器丢入url,name
3.重写run方法
4.启动线程
*/
实现Runnable接口
package com.teatea.demo01;
public class TestThread3 implements Runnable{
@Override
public void run() {
//run方法线程体
for (int i = 0; i < 20; i++) {
System.out.println("我在看代码---"+i);
}
}
public static void main(String[] args) {
//m创建Runnable接口的实现类对象
TestThread3 testThread3 =new TestThread3();
//创建线程对象,通过线程对象来开启我们的线程,代理
Thread thread = new Thread(testThread3);
thread.start();
for (int i = 0; i < 200; i++) {
System.out.println("我在学习多线程---"+i);
}
}
}
实例—网图下载代码(Runnable接口)
package com.teatea.demo01;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.net.URL;
//练习Thread,实现多线程同步下载图片
//2.继承类,编写构造方法
public class TestThread2 implements Runnable{
private String url;
private String name;
public TestThread2(String url,String name){
this.url = url; //文件下载地址
this.name = name; //保存文件名
}
//下载图片线程的执行体
//3.重写run方法
@Override
public void run() {
WebDownloader webDownloader = new WebDownloader();
webDownloader.downloader(url,name);
System.out.println("下载了文件名为"+name+"的文件");
}
//4.线程启动
public static void main(String[] args) {
TestThread2 testThread2 = new TestThread2("https://pic1.zhimg.com/v2-7c168a484333f45b2315c9d1afa13d74_r.jpg?source=1940ef5c","图片2");
TestThread2 testThread3 = new TestThread2("https://pic1.zhimg.com/v2-7c168a484333f45b2315c9d1afa13d74_r.jpg?source=1940ef5c","图片3");
new Thread(testThread2).start();
new Thread(testThread3).start();
}
}
//1.下载器
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方法出现问题");
}
}
}
/*
1.写一个下载器,里面有下载方法
2.实现一个线程类,用TestThread2继承Thread类
用构造器丢入url,name
3.重写run方法
4.启动线程
*/
小结:两种代码对比
- 继承Thread类
- 子类继承Thread类具备多线程能力
- 启动线程:子类对象.start()
- 不建议使用:避免OOP单继承局限性
- 实现Runnable接口
- 实现Runnable接口具有多线程能力
- 启动线程:传入目标对象+Thread对象.start()
- 推荐使用:避免继承局限性,灵活方便,方便同一个对象被多个线程使用
初始并发问题
package com.teatea.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();
}
//拿到线程当前执行线程的名字--->Thread.currentThread().getName()
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();
new Thread(ticket,"小茶").start();
new Thread(ticket,"小发").start();
}
}
案例—龟兔赛跑
package com.teatea.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();
}
}
//判断比赛是否结束
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 is" + winner);
return true;
}
}
return false;
}
public static void main(String[] args) {
Race race = new Race();
new Thread(race,"兔子").start();
new Thread(race,"乌龟").start();
}
}
/*
步骤总结:
1.构造判断方法,判断是否有赢家
2.implement Runnable,重写run方法,判断比赛是否结束,true为停止,否则输出跑了多少步
3.给兔子制造延时
4.main方法启动线程
*/
标签:name,Thread,线程,new,public,String
From: https://www.cnblogs.com/bobocha/p/16756521.html