1.Thread class 继承Thread类
-自定义线程类继承Thread类 -重写run()方法,编写线程执行体 -创建线程对象,调用start()方法启动线程
不建议使用:避免OOP单继承局限性
例子在上一篇博客
2.==Runnable接口 == 实现Runnable接口
定义MyRunnable类实现Runnable接口 实现run()方法,编写线程执行体 创建线程对象,调用start()方法启动线程 建议使用:避免单继承局限性,灵活方便,方便同一个对象被多个线程使用
与方法一的不同之处: 启动方式不同:
继承Thread类:子类对象.start(); 实现Runnable接口:传入目标对象+Thread对象.start();
new Thread(test).start();模拟买票
public class TestThread1 implements Runnable{ private static int ticketNum = 10; @Override public void run() { // TODO Auto-generated method stub while(true) { if(ticketNum<=0) { break; } //模拟延时 try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"-->拿到了第"+ticketNum--+"票"); } } public static void main(String[]args) { TestThread1 ticket = new TestThread1(); new Thread(ticket,"小明").start(); new Thread(ticket,"老师").start(); new Thread(ticket,"黄牛党").start(); } }代码运行后结果: 发现问题:多个线程操作同一个资源的情况下,线程不安全,数据紊乱;
龟兔赛跑的例子
package com.wy1104Thread2; /*首先来个赛道距离,然后要离终点越来越近 判断比赛是否结束 打印出胜利者 龟兔赛跑开始 兔子需要睡觉。模拟兔子睡觉 最终,乌龟赢得比赛*/ public class Race implements Runnable{ //胜利者 private static String winner; @Override public void run() { // TODO Auto-generated method stub for(int i=0;i<=100;i++) { //模拟兔子休息 if(Thread.currentThread().getName().equals("兔子")&& i%10==0) { try { Thread.sleep(5); } catch (InterruptedException e) { // TODO Auto-generated catch block 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(); } }结果如下:
3.Callable接口 实现Callable接口