线程创建
继承Thread类
//线程创建方式1:继承thread1,重写run方法,调用start开启线程
public class Thread1 extends Thread {
@Override
public void run() {
//run方法线程体
for (int i = 0; i < 20; i++) {
System.out.println("我在看代码"+i);
}
}
public static void main(String[] args) {
//创建线程对象,调用start方法
Thread1 thread1 = new Thread1();
thread1.start();
//主线程
for (int i = 0; i < 20; i++) {
System.out.println("我在学习"+i);
}
}
}
/**
* 多线程并发网络下载器
* WebDownloader实现了网络图片下载功能;downloader方法输入为目标链接地址、下载图片文件名;结果为保存对应文件到本地
* Thread2类中的run方法调用downloader方法;并且通过start实现多线程并发下载图片
* 结果显而易见 执行具有无序性
*/
//多线程同步下载图片
public class Thread2 extends Thread {
private String url;
private String name;
public Thread2(String url, String name) {
this.url = url;
this.name = name;
}
@Override
public void run() {
WebDownloader webDownloader = new WebDownloader();
webDownloader.downloader(url, name);
System.out.println("文件名" + name);
}
public static void main(String[] args) {
Thread2 thread21 = new Thread2("/i/ll/?i=2711126564c842689248e53bbf4d85e8.png", "t1.png");
Thread2 thread22 = new Thread2("/i/ll/?i=4b97a32c6d9f4caa8617099065d02e3c.png", "t2.png");
Thread2 thread23 = new Thread2("/i/ll/?i=419537bd2d5e4fdfaa70fb8b8ed17663.png", "t3.png");
thread21.start();
thread22.start();
thread23.start();
}
}
//下载器
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方法出现问题");
}
}
}
实现Runnable接口
//线程创建方式2:重写Runnable,重写run方法,执行线程丢入runnable接口实现类,调用start开启线程
public class Thread3 implements Runnable{
@Override
public void run() {
//run方法线程体
for (int i = 0; i < 20; i++) {
System.out.println("我在看代码"+i);
}
}
public static void main(String[] args) {
Thread3 thread3 = new Thread3();
//创建线程对象,调用start方法(区分于继承Thread,将new的对象当参数new一个Thread)
new Thread(thread3).start();
//主线程
for (int i = 0; i < 20; i++) {
System.out.println("我在学习"+i);
}
}
}
实现Callable接口
对比
高并发问题
买火车票
package thread;
//高并发模拟之买火车票
public class GetTicket implements Runnable{
private int ticket = 10;
@Override
public void run() {
while(true){
if(ticket<=0) break;
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"拿到了第"+ticket--+"张票");
}
}
public static void main(String[] args) {
GetTicket t1 = new GetTicket();
new Thread(t1,"xiaoming").start();
new Thread(t1,"xiaohong").start();
new Thread(t1,"xiaogang").start();
//结果:除了结果不可预测,还有多个线程共用一张票的情况
}
}
龟兔赛跑
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%50==0) {//兔子到50开始睡觉
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if(isGameOver(i)) break;
System.out.println(Thread.currentThread().getName()+"跑了"+i+"步");
}
}
private boolean isGameOver(int step){
if(step == 100){
winner = Thread.currentThread().getName();
System.out.println("winner is "+winner);
}
return winner != null || step >= 100;
}
public static void main(String[] args) {
Race race = new Race();
new Thread(race,"兔子").start();
new Thread(race,"乌龟111").start();
}
}
静态代理_Runnable原理
/**
* 静态代理:
* 设计一个接口,
* 真实对象和代理对象都要实现这个接口,
* 代理对象代理真实对象,
* 真实对象专注做自己的事,
* 代理对象代做真实对象做不到的事,
* 这就是Runnable的原理-> new Thread(myThread).start();
*/
public class StaticProxy {
public static void main(String[] args) {
/*You you = new You();
WeddingCompany weddingCompany = new WeddingCompany(you);
weddingCompany.marry();*/
//这么写和多线程实现Runnable一样
new WeddingCompany(new You()).marry();
}
}
interface Marry{
void marry();
}
//真实角色,我去结婚
class You implements Marry{
@Override
public void marry() {
System.out.println("我结婚了");
}
}
//代理角色,婚庆公司帮我做before和after
class WeddingCompany implements Marry{
private Marry target;
public WeddingCompany(Marry target) {
this.target = target;
}
@Override
public void marry() {
before();
this.target.marry();
after();
}
void before(){
System.out.println("收钱");
}
void after(){
System.out.println("打扫");
}
}
Lambda表达式
/**
* 推导了lambda表达式简化函数式编程的过程
* 如果一个接口只有一个函数,实例化它相当于调用这个函数
* 用lambda表达式可以极大简化调用过程
*/
public class TestLamda {
//3.静态内部类
static class Like2 implements ILike{
@Override
public void lambda() {
System.out.println("i like lambda2");
}
}
public static void main(String[] args) {
Like like = new Like();
like.lambda();
Like2 like2 = new Like2();
like2.lambda();
//4.局部内部类
class Like3 implements ILike{
@Override
public void lambda() {
System.out.println("i like lambda3");
}
}
Like3 like3 = new Like3();
like3.lambda();
//5.匿名内部类
like = new Like() {
@Override
public void lambda() {
System.out.println("i like lambda4");
}
};
like.lambda();
//6.lambda简化
ILike like4 = ()-> {
System.out.println("i like lambda5");
};
like4.lambda();
}
}
//1.函数接口
interface ILike{
void lambda();
}
//2.实现类
class Like implements ILike{
@Override
public void lambda() {
System.out.println("i like lambda");
}
}
//lambda表达式简化
public class Testlam {
public static void main(String[] args) {
int n = 5;
//简化:可以不带参数类型;一个参数可以不带();void方法且只有一行可以不带{}
Test1 myT = n1-> {return n1*n1;};
Test2 myT2 = n1-> System.out.println(n1*n1);
int re = myT.reSequre(n);
System.out.println(re);
myT2.reSequre(n);
}
}
interface Test1{
int reSequre(int n);
}
interface Test2{
void reSequre(int n);
}
线程状态和实现
停止线程stop
package state;
/**
* 线程停止方法:设定标志位,调用stop()方法使标志位变为0,进而停止线程
*/
public class TestStop implements Runnable {
boolean flag = true;//标志位
@Override
public void run() {
int i = 0;
while (flag){//停止控制
System.out.println("run thread"+i++);
}
}
//停止线程
public void stop(){
this.flag = false;
}
public static void main(String[] args) {
TestStop testStop = new TestStop();
new Thread(testStop).start();//线程
//主线程
for (int i = 0; i < 1000; i++) {
System.out.println("main"+i);
if(i==900){
testStop.stop();
System.out.println("停止 i="+i);
}
}
}
}
线程休眠sleep(进入阻塞)
//sleep模拟时钟
public class TimeClock {
public static void main(String[] args) {
Clock clock = new Clock(10);
new Thread(clock).start();
}
}
class Clock implements Runnable{
@Override
public void run() {
this.clock();
}
private int clk;
public Clock(int clk) {
this.clk = clk;
}
void clock(){
while(true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("time:"+this.clk--);
if(clk<0){
System.out.println("time out");
break;
}
}
}
}
线程礼让yield(进入就绪)
执行结果:可能礼让成功,abab;可能礼让失败,aabb
本质是让进程由执行变为就绪,竞争下一次的执行机会;取决于调度算法
线程强制执行join
执行结果:main中 i==200时 执行thread中的语句直到结束,并且其他线程阻塞
观测线程状态Thread.State
结果:
NEW——RUNNABLE——若干个TIMED-WAITIN——TERMINATED
新建 运行/就绪 睡眠(阻塞) 终止
线程优先级
守护daemon线程
/**
* 守护线程,可以不用确保其运行完毕
* 运行结果:manba out之后,god像蛆一样再运行了几句,然后痛苦的似了
标签:void,笔记,线程,println,new,多线程,public,out
From: https://www.cnblogs.com/autismer-ustcsse/p/17978717