1. 方案一:继承thread.
1 package com.example.demo; 2 3 4 5 //1. 方法1,继承thread类:Thread implements Runnable 6 package com.example.demo; 7 public class ThreadCreateDemo1 { 8 public static void main(String[] args) { 9 MyThread thread = new MyThread(); 10 MyThread thread1 = new MyThread(); 11 MyThread thread2 = new MyThread(); 12 thread.start(); //该方法调用多次,出现IllegalThreadStateException 13 thread1.start(); //该方法调用多次,出现IllegalThreadStateException 14 thread2.start(); //该方法调用多次,出现IllegalThreadStateException 15 } 16 } 17 18 class MyThread extends Thread { 19 @Override 20 public void run() { 21 //super.run(); 22 System.out.println("hellow_world!"); 23 } 24 }
2.方案二: 实现runnable.
1 //2. 实现runnable:Thread(Runnable target) 2 public class ThreadCreateDemo1 { 3 public static void main(String[] args) { 4 MyRunnable runnable = new MyRunnable(); 5 MyRunnable runnable1 = new MyRunnable(); 6 MyRunnable runnable2 = new MyRunnable(); 7 MyRunnable runnable3 = new MyRunnable(); 8 new Thread(runnable).start(); 9 new Thread(runnable1).start(); 10 new Thread(runnable2).start(); 11 new Thread(runnable3).start(); 12 13 } 14 } 15 16 class MyRunnable implements Runnable { 17 public void run() { 18 System.out.println("通过Runnable创建的线程!"); 19 } 20 } 21
3.案例
package cn.tedu.thread; public class WaitNotifyDemo { public static void main(String[] args) { //创建学生类对象 Student s=new Student(); s.setName("lili"); s.setGender('女'); //开启线程 new Thread(new Ask(s)).start(); new Thread(new Change(s)).start(); } } //线程所在的类---问问题 class Ask implements Runnable{ // 引入学生类对象 private Student s; public Ask(Student s){ this.s=s; } @Override public void run() { // TODO Auto-generated method stub //表示问问题的结果 while(true){ synchronized (s) { //释放线程执行权---等待 if(s.flag==false) try { s.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } //输出 System.out.println ("老师你好,我是"+s.getName() +",是一个"+s.getGender()+ "生,想问问题..."); //唤醒线程 s.notify(); //改变布尔值 s.flag=false; } } } } //线程所在的类---换学生 class Change implements Runnable{ //引入学生类对象 private Student s; public Change(Student s){ this.s=s; } @Override public void run() { // TODO Auto-generated method stub while(true){ synchronized (s) { //线程等待 if(s.flag==true) try { s.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } // if (s.getName().equals("tom")) { s.setName("lili"); s.setGender('女'); } else { s.setName("tom"); s.setGender('男'); } //线程唤醒 s.notify(); //改变布尔值 s.flag=true; } } }} //学生类 class Student{ //属性 private String name; private char gender; // boolean flag=true; public char getGender() { return gender; } public void setGender(char gender) { this.gender = gender; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
4.案例
package cn.tedu.thread; public class SellTicketText1 { public static void main(String[] args) { //创建票类对象 Ticket t=new Ticket(); //设置票数 t.setCount(100); //四个售票员 Seller s1=new Seller(t); Seller s2=new Seller(t); Seller s3=new Seller(t); Seller s4=new Seller(t); /* //开启线程 new Thread(s1,"A").start(); new Thread(s2,"B").start(); new Thread(s3,"C").start(); new Thread(s4,"D").start();*/ ////开启线程 //*this指代当前类对象每个对象单独加锁---一个对象呗四个线程执行 new Thread(s1,"A").start(); new Thread(s1,"B").start(); new Thread(s1,"C").start(); new Thread(s1,"D").start(); } } //卖票---线程的代码逻辑 class Seller implements Runnable{ //引入票类 Ticket t; //有参构造 public Seller(Ticket t){ this.t=t; } //线程代码逻辑---卖票的过程 //同步方法锁 @Override public synchronized void run() { // TODO Auto-generated method stub //卖票---循环 while(true){//票卖结束就是票数为0 //同步代码块锁---(锁对象)---被线程共享 //synchronized (t) {//Math.class Seller.class // 判断条件 if (t.getCount() <= 0) { break; } // 设置新的票数 t.setCount(t.getCount() - 1); // 打印具体哪个售票员卖的---具体是哪个线程执行的 // Thread.currentThread()---当前正在执行的线程 System.out.println(Thread.currentThread().getName() + "卖了一张票,还剩" + t.getCount() + "票..."); //} } } } //表示票类 class Ticket{ //属性 //票数 private int count; public int getCount() { return count; } public void setCount(int count) { this.count = count; } }
使用继承方式的好处是方便传参,你可以在子类里面添加成员变量,通过set方法设置参数或者通过构造函数进行传递,而如果使用Runnable方式,则只能使用主线程里面被声明为final的变量。不好的地方是Java不支持多继承,如果继承了Thread类,那么子类不能再继承其他类,而Runable则没有这个限制。前两种方式都没办法拿到任务的返回结果,但是Callable方式可以