start()
方法之后,该线程即进入就绪转态;就绪状态的线程处于就绪队列中,要等待JVM线程调度器的调度。run()
方法。sleep()
(睡眠),suspend()
(挂起)方法,或者失去了所占用的资源后,线程进入阻塞状态;再次之后,可重新进入就绪状态;
wait()
方法。sleep()
或join()
发出IO请求时,会进入阻塞状态。当sleep() 状态超时,join() 等待线程终止或超时,或者 I/O 处理完毕,线程重新转入就绪状态。每一个 Java 线程都有一个优先级,这样有助于操作系统确定线程的调度顺序。
Java 线程的优先级是一个整数,其取值范围是 1 (Thread.MIN_PRIORITY ) - 10 (Thread.MAX_PRIORITY )
,1-10级。
默认情况下,每一个线程都会分配一个优先级NORM_PRIORITY(5)
。
String getName()
返回线程的名称static Thread currentThread()
,使用线程中的getName()方法获取线程void setName(String name)
方法改变线程名称Thread(String name)
,让父类给取一个名字;public static void sleep(long millis)
:使当前正在执行的线程以指定的毫秒数暂停(暂时停止执行),毫秒数结束之后,线程继续执行public class MyThread extends Thread{ @Override public void run(){ System.out.println(getName()); } } public class Demo01GetThread{ //创建Thread类的子类对象 MyThread mt=new MyThread(); //调用start()方法,开启新线程 mt.start();//--------------------------"Thread-0" new MyThread().start();//--------------"Thread-1" new MyThread().start();//--------------"Thread-2" } public class MyThread extends Thread{ @Override public void run(){ Thread t=Thread.currentThread(); System.out.println(t); System.out.println(t.getName()); } } public class Demo01GetThread{ //创建Thread类的子类对象 MyThread mt=new MyThread(); //调用start()方法,开启新线程 mt.start();//--------------------------"Thread[Thread-0,5,main]/Thread-0" new MyThread().start();//--------------"Thread[Thread-1,5,main]/THread-1" new MyThread().start();//--------------"Thread[Thread-2,5,main]/Thread-2" System.out.println(Thread.currentThread().getName());//-------"main" }
public class Demo01GetThread{ //创建Thread类的子类对象 MyThread mt=new MyThread(); mt.setName("张三"); System.out.println(mt.getName()); } public class MyThread extends Thread{ @Override public MyThread(){} public MyThread(String name){ super(name);//调用父类的带参构造方法``Thread(String name),让父类给取一个名字 } public void run(){ Thread t=Thread.currentThread(); System.out.println(t); System.out.println(t.getName()); } }
public class Demo01Sleep{ public static void main(String[] args){ for(int i=1;i<=60;i++){ System.out.println(i); try{ Thread.sleep(1000); }catch(InterruptedException e){ e.printStackTrace(); } } } }
将类声明为Tread的子类,该子类重写Thread类的run方法。接下来可以分配该子类的实例。
run()
方法,设置线程任务(即线程要做什么);Start()
方法,开启新线程,间接执行run方法;
void start()
使该线程开始执行; Java虚拟机调用该线程的run方法。java程序属于抢占式调度, 那个线程的优先级高,那个线程优先执行;同一个优先级,随机选择一 个执行
public class MyThread extends Thread{ @Override public void run(){ for(int i=0;i<20;i++){ System.out.println("run:"+i); } } } public class Demo01Tread{ public static void main(String[] args){ //创建子类对象 MyThread mt=new MyThread(); //调用start()方法,间接执行run()方法 mt.start(); //main主线程,此时两线程并发执行 for(int i=0;i<20;i++){ System.out.println("main:"+i) } } }
并发的抢占CPU资源
创建线程的另-种方法是声明实现Rumable接口的类。该类然后实现run方法。然后可以分配该类的实例,在创建Thread 时作为一个参数来传递并启动。
java. Lang. Runnable
Runnable接口应该由那些打算通过某一线程执行其实例的类来实现。 类必须定义一个称为run 的无参数方法。
java. Lang. Thread类的构造方法
Thread(Runnable target)
分配新的Thread 对象。
Thread(Runnable target, String name)
分配新的Thread 对象。
run()
方法start()
方法,开启新线程public class MyRunClass implements Runnable{//--------实现Runnable接口 @Override void run(){ //------------------------------------重写run方法 System.out.println("Runnable线程:"+Thread.currentThread().getName()); } } public class Demo01Runnable{ public static void main(String[] args){ //写法1 MyRunClass rc=new MyRunClass();//--------创建该Runnable接口实现类的对象 Thread mt=new Thread(rc);//----------用该对象创建Thread类对象 mt.start();//----------------------------调用Thread类对象中的start()方法,开启新线程 //写法2 new Thread(){ @Override public void run(){ for(int i=0;i<20;i++){ System.out.println(i); } } }.start(); //写法3 Runnable r=new Runnable(){ @Override public void run(){ for(int i=0;i<20;i++){ System.out.println(i); } } } new Thread(r).start(); //写法4 new Thread(new Runnable(){ @Override public void run(){ for(int i=0;i<20;i++){ System.out.println(i); } } }).start(); //写法5:lambda表达式 new Thread(()->{ for(int i=0;i<20;i++){ System.out.println(i); } }).start(); } }
1,避免了单继承的局限性
2,增强了程序的扩展性,降低了程序的耦合性
实现Runnable接口的方式,一个任务可以用多个线程来执行。
ExecutorService ser
:ExecutorService ser =Executors.newFixedThreadPool(n);
Future<T> res=ser.submit(call1);
res.get()
ser.shutdownNow()
//1,实现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; } //2, 重写call方法,需要抛出异常值 @Override public Boolean call(){ WebDownloader webDownloader=new WebDownloader(); webDownloader.downloader(url,name); System.out.println("下载了文件名为:"+name); return true; } public static void main(String[] args){ //3,创建目标Callalbe对象,n个; TestCallable t1=new TestCallable("https://kgoe.ego.cn/gei.img/1"); TestCallable t2=new TestCallable("https://kgoe.ego.cn/gei.img/2"); TestCallable t3=new TestCallable("https://kgoe.ego.cn/gei.img/3"); //4,创建执行服务对象ExecutorService ExecutorService ser =Executors.newFixedThreadPool(3); //5,提交执行 Future<Boolean> r1=ser.submit(t1); Future<Boolean> r2=ser.submit(t2); Future<Boolean> r3=ser.submit(t3); //6,获取返回值 boolean rs1=r1.get(); boolean rs2=r2.get(); boolean rs3=r3.get(); //7,关闭执行服务 ser.shutdownNow(); } }
新的线程会开辟新的栈空间