一:线程
定义:软件中并发执行的过程
并发:
操作系统采用分时调度策略将多个程序交替运行,宏观感受是多个程序同时并行的现象叫做“并发”
java中的多线程
Tread类:
1 Thread 线程
Thread 封装了操作系统对线程调度过程
使用Thread类创建了线程
->继承Thread类继承了复杂的线程管理
->重写run()方法,就是并发执行的方法,线程执行期间,将执行修改以后run方法
->用start()方法,启动线程:将线程交给操作系统,又操作系统调度管理,操作系统会执行run方法
->注意:直接执行run方法不是线程执行
线程代码
calss MyThread extends Thread{ public void run(){ System.out.printnln("你好java"); } } MyThread t =new MyThread(); t.start();
2 使用Runnable接口创建线程
--->1 实现Runnable接口,具体是实现run方法
--->2创建接口的子类实例
--->3创建线程对象,将接口的实例作为线程参数
--->4调用start方法,启动线程
案例:
class Myrunnable implements Runnable { public void run(){ System.out.println("hello word"); } } //启动线程 public class Demo2 { public static void main(String[] args) { //创建Runnable 来创建线程 Myrunnable t=new Myrunnable(); //创建线程对象 与Runnable子类对象作为从参数 Thread a=new Thread(t); //启动线程 a.start(); } }
3 线程状态;
下面的属于计算机操作系统进程的内容:
-new 新建状态:使用new运算创建的线程对象,是线程的初始状态
-Runnable:可运行状态,也称就绪状态,线程已经交给操作系统,又称系统负责调用,等到合适的时间准备运行
-Running:正在运行的状态,操作系统分配时间片段给线程,线程被调度的到CPU内执行,单核系统中,只有一个线程处在Running状态
-Dead:死亡状态-->垃圾回收
4 使用Runnable接口创建线程的好处是,当前的类可以继承于其他的类,也可以继承其他的接口。
5 Thread的静态方法curreentThread()方法可以获取当前的调用代码段的当前线程
测试代码:
public class Dem03 { public static void main(String[] args) { Thread1 t1=new Thread1(); Thread2 t2=new Thread2(); t1.start(); t2.start(); /* * 1.java启动时候会主动启动主线程 * 2 .main 被主线程调用 */ Thread tt=Thread.currentThread(); System.out.println(tt.getName()); } public void test(){ //调用方法的线程是谁 System.out.println("text"); //利用Thread类提供了一个静态工具方法 //获取正在正在调用的方法的线程对象 //current 当前 Thread t=Thread.currentThread(); System.out.println(t.getName()); } } class Thread1 extends Thread{ public void run(){ Dem03 d =new Dem03(); d.test(); } } class Thread2 extends Thread{ public void run(){ Dem03 d =new Dem03(); d.test(); } }
6 线程状态:
测试代码:
public class Demo05 { public static void main(String[] args) throws InterruptedException { Thread t1=new Thread(){ public void run(){ System.out.println("hello world"); System.out.println(getState()); System.out.println(isAlive()); } }; System.out.println(t1.getState());//NEW System.out.println(t1.isAlive());//false t1.start();//运行t1 Thread.sleep(1000);// 等待1秒t1运行完事,执行run方法 System.out.println(t1.getState());//TERMINATED System.out.println(t1.isAlive());//false t1.start();//这句话会导致异常,因为死亡的状态不能再次启动运行 } }
7 后台线程:守护线程
守护线程与普通在表现上没有什么区别,我们只需要通过Thread提供的方法来设定即可:
-void setDaemon(boolean)
-当参数为true时该线程为守护线程
-(比如:后台线程可以用于后台背景音乐播放器控制)
public class Demo06 { public static void main(String[] args) { //前台线程 TestThread t1=new TestThread(); t1.setName("T1"); t1.time=3000; //前台线程 TestThread t2=new TestThread(); t2.setName("T2"); t2.time=5000; TestThread t3=new TestThread(); t3.setName("T3"); t3.time=10000; //将t3设置为后台线程 t3.setDaemon(true); t1.start(); t2.start(); t3.start(); System.out.println("Bye");//主线程结束 } } class TestThread extends Thread{ int time; public void run(){ System.out.println(getName()+"start!"); try{ sleep(time);//父类没有该异常。子类必须捕获,不能抛出 }catch(InterruptedException e){ e.printStackTrace();//打印堆栈信息 } System.out.println(getName()+"End!"); } } 测试结果: /* * 当全部前台线程都结束时候, * 如果后台线程还没有结束,这时候后台将被提前结束 */ T1start! T2start! Bye T3start! T1End! T2End!
8 Sleep方法;
-用于使程序进行适当的休眠
-唤醒机制,用于两个线程之间协调工作
-在进入Sleep block时候,线程不占用处理器,操作系统可以调度其他线程其他线程在处理器中执行。
Thread的静态方法sleep用于市当前进程进入阻塞状态:
-static void sleep(long ms)
该方法会使的当前线程进入阻塞状态指定毫秒,当前阻塞指定毫秒后,当前经常重新出现Runnable状态,等待分配时间片
该方法申明抛出一个InterputException,所以在使用该方法需要捕获这个异常
try{
sleep(time)
}catch(InterputException e){
e.printStackTrance();
//被打断,被弄醒}
测试程序:
public class Demo07 { public static void main(String[] args) { SleepTread t1=new SleepTread(); SleepTread t2=new SleepTread(); t1.time=1000; t2.time=2000; t1.other=t2; t1.start(); t2.start(); } } class SleepTread extends Thread{ int time; SleepTread other; public void run(){ System.out.println(getName()+"开始"); try{ sleep(time); System.out.println("大梦谁先觉!"); //在t1中叫醒t2 other.interrupt(); }catch(InterruptedException e){ e.printStackTrace(); System.out.println("被弄醒!"); } System.out.println(getName()+"结束"); } } 测试结果: Thread-0开始 Thread-1开始 大梦谁先觉!java.lang.InterruptedException: sleep interrupted Thread-0结束 被弄醒! Thread-1结束
at java.lang.Thread.sleep(Native Method)
at day01.SleepTread.run(Demo07.java:23)
9 yield 方法
-Thread的静态方法yield:
-static void yield()
-该方法用于当前线程主动让出当次CPU时间片回到Runnable,等待非陪分配时间片
测试代码:
public class Demo08 { public static void main(String[] args) { Thread4 t1=new Thread4(); Thread4 t2=new Thread4(); t1.str="a"; t2.str="b"; t1.start(); t2.start(); } } class Thread4 extends Thread{ String str; public void run(){ for(int i=0;i<100;i++){ System.out.println(getName()+"->"+str); /* * 在运行期间,让出当前线程正在占用的处理器资源 */ yield(); } } } 测试结果: Thread-1->b Thread-1->b Thread-0->a Thread-1->b Thread-0->a
10 join方法:
-void join()
-该方法等于等待当前线程结束。
-该方法申明抛出InterruptException
import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Random; /** * 一个线程1用于产生十个随机数,另一个线程2 等到长生完数据后用于读这十个随机数进行排序 * @author soft01 * */ public class Demo09 { public static void main(String[] args) { List<Integer> list=new ArrayList<Integer>(); Thread7 t1=new Thread7(); t1.list=list; Thread8 t2=new Thread8(); t2.list=list; t2.t1=t1; t1.start(); t2.start(); } } class Thread7 extends Thread{ Random rand=new Random(); List<Integer> list; public void run(){ for(int i=0;i<10;i++){ list.add(rand.nextInt(100));//0-99,(int)(Math.random()*100); } System.out.println(list); } } class Thread8 extends Thread{ List<Integer> list; Thread7 t1; public void run(){ try{ t1.join(); //等待t1结束 Collections.sort(list); //等待排序后的结果 System.out.println(list); }catch(InterruptedException e){ e.printStackTrace(); //被打断结束 } } }