多线程的最基础使用
继承Thread
package com.example.demo.Thread; public class MyThreadTest1 extends Thread{ @Override public void run() { for (int i = 0; i < 20; i++) { System.out.println("我是run方法-----"); } } public static void main(String[] args) { MyThreadTest1 myThreadTest1=new MyThreadTest1(); // run方法和start()的区别在于: // 调用run(),只有主线程一条执行路径 // 调用start(),子线程执行run()方法,多条执行路径,主线程和子线程并行交替执行 myThreadTest1.start(); for (int i = 0; i < 2000; i++) { System.out.println("我是main函数-----"); } } }
实现Runnable接口
public class MyRRunableTest1 implements Runnable{ @Override public void run() { for (int i = 0; i < 2000; i++) { System.out.println("我是run方法-----"); } } public static void main(String[] args) { //创建runnable接口实现类对象 MyThreadTest1 myThreadTest1=new MyThreadTest1(); // 第一种写法、创建线程对象开启线程,代理类对象 // Thread thread = new Thread(myThreadTest1); // thread.start(); // 第二种写法 new Thread(myThreadTest1).start(); for (int i = 0; i < 2000; i++) { System.out.println("我是main函数-----"); } } }
利用实现Runnable接口做一个一份资源多个代理的举例,发现问题:
一个资源多个线程用,线程不安全,可能导致并发
package com.example.demo.Thread; public class MyRunnableTest2 implements Runnable{ @Override public void run() { //一份资源多个代理 for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName()+"拿到了第"+i+"票"); } } public static void main(String[] args) { MyRunnableTest2 myRunnableTest2=new MyRunnableTest2(); // new Thread(myRunnableTest2,"小丽(名称)").start(); new Thread(myRunnableTest2,"小丽").start(); new Thread(myRunnableTest2,"小张").start(); new Thread(myRunnableTest2,"小王").start(); // 一份资源多个代理 发现问题,一个资源多个线程用,线程不安全,可能导致并发 // 运行结果: // 小丽拿到了第0票 小丽拿到了第1票 小丽拿到了第2票 小丽拿到了第3票 小丽拿到了第4票 小丽拿到了第5票 // 小张拿到了第0票 小张拿到了第1票 小张拿到了第2票 小张拿到了第3票 小张拿到了第4票 小张拿到了第5票 // 小王拿到了第0票 小王拿到了第1票 小王拿到了第2票 小王拿到了第3票 小王拿到了第4票 小王拿到了第5票 } }
小结:
# 继承Thread类
-
-
- 子类继承Threa类具备多线程能力
- 启动线程:子类对象.start()
- 不建议使用:避免OOP单继承局限性
-
# 实现Runnabile接口
- 实现接口Runnable具有多线程能力
- 启动线程: 传入目标对象+thread对象.start() 例如:new Thread(目标对象).start()
- 推荐使用:避免单继承局限性,灵活方便,方便同一个对象被多个线程使用
龟兔赛跑案例:
package com.example.demo.Thread; public class Ract implements Runnable{ private static String winner; //胜利者 @Override public void run() { for (int i = 0; i <= 100; i++) { //判断比赛是否结束 boolean b = gameOver(i); // 比赛结束,停止程序 if (b==true){ break; } //模拟兔子休息 // if (Thread.currentThread().getName().equals("兔子")){ // try { // Thread.sleep(100); // } catch (InterruptedException e) { // e.printStackTrace(); // } // } System.out.println(Thread.currentThread().getName()+"---跑了"+i+"步"); } } //判断比赛是否完成 boolean gameOver(int step){ if(winner!=null ){//已经有胜利者 return true; }else{ if (step>=100) { winner= Thread.currentThread().getName(); System.out.println("winner is "+ winner); } } return false; } public static void main(String[] args) { Ract ract=new Ract(); new Thread(ract,"兔子").start(); new Thread(ract,"乌龟").start(); } }