多线程
线程、进程(Process)、多线程(Thread)
程序>进程>线程
进程是程序执行的过程,是系统分配的,里面有多个线程,真正执行的是线程,main是主线程。
1.龟兔赛跑
- 首先来个赛道距离,然后离终点越来越近
- 判断比赛是否结束
- 打印出胜利者
- 龟兔赛跑开始
- 故事中是乌龟赢的,兔子需要睡觉,所以我们来模拟兔子睡觉
- 终于,乌龟赢得了比赛
//模拟龟兔赛跑
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+"步");
}
}
//判断是否完成比赛
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 static void main(String[] args) {
Race race = new Race();
new Thread(race,"兔子").start();
new Thread(race,"乌龟").start();
}
}
2.实现Callable接口(了解)
/*
callable的好处:
1.可以定义返回值
2.可以抛出异常
*/
//线程创建方式三:实现callable接口
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() {
WebDownloader webDownloader = new WebDownloader();
webDownloader.downloader(url,name);
System.out.println("下载了文件"+name);
return true;
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
TestCallable t1 = new TestCallable("https://img-blog.csdnimg.cn/20190306210317183.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwMzAxMDI2,size_16,color_FFFFFF,t_70","b.jpg");
TestCallable t2 = new TestCallable("https://img-blog.csdnimg.cn/20190306210317183.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwMzAxMDI2,size_16,color_FFFFFF,t_70","c.jpg");
TestCallable t3 = new TestCallable("https://img-blog.csdnimg.cn/20190306210317183.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwMzAxMDI2,size_16,color_FFFFFF,t_70","d.jpg");
//创建执行服务
ExecutorService ser = Executors.newFixedThreadPool(3);
//提交执行
Future<Boolean> r1 = ser.submit(t1);
Future<Boolean> r2 = ser.submit(t2);
Future<Boolean> r3 = ser.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);
//关闭服务
ser.shutdown();
}
}
3.静态代理模式
/*
静态代理模式总结
真实对象和代理对象要实现同一个接口
代理对象要代理真实角色,
*/
//好处:
// 代理对象可以做很多真实对象做不了的事情
// 真实对象就专注做自己的事情
public class StaticProxy {
public static void main(String[] args) {
WeddingCompany weddingCompany = new WeddingCompany(new You());
weddingCompany.HappyMarry();
}
}
interface Marry{
//人间四大喜事
void HappyMarry();
}
//真实角色,你去结婚
class You implements Marry{
@Override
public void HappyMarry() {
System.out.println("结婚");
}
}
//代理角色
class WeddingCompany implements Marry{
//真实目标角色
private Marry target;
public WeddingCompany(Marry target) {
this.target = target;
}
@Override
public void HappyMarry() {
before();
this.target.HappyMarry();//这就是真实对象
after();
}
private void before(){
System.out.println("结婚之前");
}
private void after(){
System.out.println("结婚之后");
}
}
4.Lamda表达式
public class TestLambda2 {
public static void main(String[] args) {
//lambda表示简化
Ilove love =(int a)->{
System.out.println("i love you-->"+a);
};
//简化1:去掉参数类型
love = (a)->{
System.out.println("i love you-->"+a);
};
//简化2:简化括号
love = a->{
System.out.println("i love you-->"+a);
};
//简化3:去掉花括号
love = a -> System.out.println("i love you-->"+a);
love.love(2);
//总结:
//lambda表达式只能有一行代码的情况下才能简化成为一行,如果有多行,那么就用代码包裹
//前提是接口为函数式接口,只能有一个方法
//多个参数,也可以去掉参数类型。要去掉就都去掉,必须加上括号。
}
}
interface Ilove{
void love(int a);
}
5.线程停止
线程停止
public class TestStop implements Runnable{
//设置一个标志位
private 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){
//调用stop方法切换标志位,让线程停止
testStop.stop();
System.out.println("线程停止了");
}
}
}
}
6.线程休眠(sleep)
模拟延迟
//模拟网络延时:放大问题的发生性
public class TestSleep 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) {
TestSleep ticket = new TestSleep();
new Thread(ticket,"小明").start();
new Thread(ticket,"老师").start();
new Thread(ticket,"黄牛党").start();
}
}
模拟倒计时
//模拟倒计时
public class TestSleep2 {
public static void main(String[] args) throws InterruptedException {
//模拟倒计时
tenDown();
//打印当前系统时间
Date startTime = new Date(System.currentTimeMillis());
while (true){
try {
Thread.sleep(1000);
System.out.println(new SimpleDateFormat("HH:mm:ss").format(startTime));
startTime = new Date(System.currentTimeMillis());//更新当前时间
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void tenDown() throws InterruptedException {
int num =10;
while (true){
Thread.sleep(1000);
System.out.println(num--);
if(num<=0){
break;
}
}
}
}
7.线程礼让(yield)
//测试礼让线程
//礼让不一定成功,看CPU心情
public class TestYield {
public static void main(String[] args) {
MyYield myYield = new MyYield();
new Thread(myYield,"a").start();
new Thread(myYield,"b").start();
}
}
class MyYield implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"线程开始执行");
Thread.yield();//礼让
System.out.println(Thread.currentThread().getName()+"线程停止执行");
}
}
8.线程强制执行(join)
//测试join方法:想象为插队
public class TestJoin implements Runnable {
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.println("线程VIP来了"+i);
}
}
public static void main(String[] args) throws InterruptedException {
//启动我们的线程
TestJoin testJoin = new TestJoin();
Thread thread = new Thread(testJoin);
thread.start();
//主线程
for (int i = 0; i < 1000; i++) {
if(i==200){
thread.join();//插队
}
System.out.println("main"+i);
}
}
}
9.观测线程状态
//观察测试线程的状态
public class TestState {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(()->{
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("//");
});
//观察状态
Thread.State state = thread.getState();
System.out.println(state);//NEW
//观察启动后
thread.start();//启动线程
state=thread.getState();
System.out.println(state);//Run
while (state!=Thread.State.TERMINATED){//只要线程不终止,就一直输出状态
Thread.sleep(100);
state = thread.getState();
System.out.println(state);
}
}
}
10.线程的优先级
先设置优先级,再启动
//测试线程的优先级
public class TestPriority {
public static void main(String[] args) {
//主线程的默认优先级
System.out.println(Thread.currentThread().getName()+"--->"+Thread.currentThread().getPriority());
MyPriority myPriority = new MyPriority();
Thread t1 = new Thread(myPriority);
Thread t2 = new Thread(myPriority);
Thread t3 = new Thread(myPriority);
Thread t4 = new Thread(myPriority);
Thread t5 = new Thread(myPriority);
Thread t6 = new Thread(myPriority);
//先设置优先级,再启动
t1.start();
t2.setPriority(1);
t2.start();
t3.setPriority(4);
t3.start();
t4.setPriority(Thread.MAX_PRIORITY);//10
t4.start();
}
}
class MyPriority implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"--->"+Thread.currentThread().getPriority());
}
}
11.守护线程(daemon)
//测试守护线程
//上帝守护你
public class TestDaemon {
public static void main(String[] args) {
God god = new God();
You you = new You();
Thread thread = new Thread(god);
thread.setDaemon(true);//默认是false表示的是用户线程,正常的线程都是用户线程...
thread.start();//上帝守护线程启动
new Thread(you).start();//你,用户线程启动
}
}
//上帝
class God implements Runnable{
@Override
public void run() {
while (true){
System.out.println("上帝保佑你");
}
}
}
//你
class You implements Runnable{
@Override
public void run() {
for (int i = 0; i < 36500; i++) {
System.out.println("你一生都开心的活着");
}
System.out.println("=========goodebye,World!");
}
}