一:通过继承方式
继承java.lang.Thread class Person extends java.lang.Thread{ private int num=50;//苹果总数 public Person(String name) { super(name); } @Override public void run() { for (int i = 0; i <50 ; i++) { if(num>0) System.out.println(super.getName()+"吃了编号为"+num-- +"的苹果"); } } } 调用 public class ExtendsThreadDemo { public static void main(String[] args) { //创建三个人(进程)吃苹果 new Person("小A").start(); new Person("小B").start(); new Person("小C").start(); } } 输出二:实现Runnable接口
class Person_1 implements Runnable{ private int num=50; @Override public void run() { for (int i = 0; i <50 ; i++) { if(num>0) System.out.println(Thread.currentThread().getName()+"吃了编号为"+num-- +"的苹果"); } } } 调用 public class ImplementsRunnableDemo { public static void main(String[] args) { Person_1 person_1=new Person_1(); //创建三个线程吃苹果 new Thread(person_1,"小").start(); new Thread(person_1,"小B").start(); new Thread(person_1,"小C").start(); } }三:实现Callable接口
与Runable相比的优点 1.相比run()方法,可以有返回值2.方法可以抛出异常3.支持泛型的返回值4.需要借助FutureTask类,比如获取返回结果
import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; //创建一个callable的实现类 class NumThread implements Callable{ @Override //实现call方法,将此线程需要执行的操作声明在call public Object call() throws Exception { int sum=0; for (int i = 1 ; i <=100 ; i++) { if(i%2==0){ System.out.println(i); sum+=i; } } return sum; } } public class ThredNew { public static void main(String[] args) { //3.创建callable接口实现类 NumThread numThread=new NumThread(); FutureTask futureTask=new FutureTask(numThread); new Thread(futureTask).start(); try { //4.获取callable的call方法返回值 Object sum=futureTask.get(); System.out.println(sum); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } }四:使用线程池
使用线程池的好处:提高响应速度,降低资源消耗,便于线程管理。
package thread_demo; import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ThreadPoolExecutor; class NumberThread implements Runnable{ @Override public void run() { for (int i = 0; i < 100; i++) { if (i%2==0){ System.out.println(Thread.currentThread().getName()+":"+i); } } } } public class ThreadPool { public static void main(String[] args) { //提供指定线程数量的线程池 ExecutorService executorService= Executors.newFixedThreadPool(10); //设置线程池的属性 ThreadPoolExecutor serverSetting=(ThreadPoolExecutor)executorService; //serverSetting.get..... //执行指定的线程操作,需要实现Runnable接口的实现类 executorService.execute(new NumberThread()); //适用于callable // executorService.submit(); //关闭线程池 executorService.shutdown(); } }五:进程的生命周期
六:java线程的一些API
名称说明currentThread()返回对当前正在执行的线程对象的引用。setName(String name)将此线程的名称更改为等于参数 name 。setPriority(int newPriority)更改此线程的优先级。start()导致此线程开始执行; Java虚拟机调用此线程的run方法。run()如果这个线程使用单独的Runnable运行对象构造,则调用该Runnable对象的run方法; 否则,此方法不执行任何操作并返回。setDaemon(boolean on)将此线程标记为 daemon线程或用户线程。sleep(long millis)使当前正在执行的线程以指定的毫秒数暂停(暂时停止执行),具体取决于系统定时器和调度程序的精度和准确性。join()等待这个线程死亡。isAlive()测试这个线程是否活着。interrupted()测试当前线程是否中断。getState()返回此线程的状态。interrupted()测试当前线程是否中断。toString()返回此线程的字符串表示,包括线程的名称,优先级和线程组。