Java- 简单了解线程 线程创建和联合线程(一)
简单的了解一下JAVA的多线程后,觉的C#好像做的更好,C#通过委托的方式来实现多线程,当然JAVA实现多线程也很方便,但还是觉的C#做的更好。那么什么是多线程?一个进程中又可以包含一个或多个线程,一个线程就是一个程序内部的一条执行线索,如果要一程序中实现多段代码同时交替运行,就需要产生多个线程。
线程的生命周期
新建→运行→中断→死亡
中断有: 1.当前线程切换到另一个线程时发生
2.执行sleep时
3.执行wait方法时,调用wait方法使线程进入等待后,如果想让他开启必须调用notify方法
看一下单线程的情况,发现运行的结果他在线程MAIN里
public class test9 { public static void main(String[] args) { new TestThread().run(); } } class TestThread { public void run() { while(true) { System.out.println(Thread.currentThread().getName()); } } }
用Thread类创建多线程
我们要实现多线程,必须编写一个继承了Thread类的子类,子类要覆盖Thread类中的run函数,在子类的run函数中编写想在新线程上运行的程序代码。启动一个新的线程,我们不是直接调用Thread的子类对象的run方法,而是调用Thread子类对象的start方法;Thread类对象的start方法将产生一个新的线程,并在该线程上运行该Thread类对象中的run方法,根据面向对象的运行时的多态性,在该线程上实际运行的是Thread子类对象的run方法。
public class test9 { public static void main(String[] args) { new TestThread().start(); while(true) { System.out.println(Thread.currentThread().getName()); } } } class TestThread extends Thread { public void run() { while(true) { System.out.println(Thread.currentThread().getName()); } } }
由于我们没有给线程设置一个名字,所以使用语句 Thread.currentThread().getName() 他最后出来的是Thread-0
那么把上面的程序改写一下,能过setName来给创建的线程取一个名字:我的第一个线程
public class test9 { public static void main(String[] args) { TestThread t1 = new TestThread("我的第一个线程"); t1.start(); while(true) { System.out.println(Thread.currentThread().getName()); } } } class TestThread extends Thread { TestThread(String name) { setName(name); } public void run() { while(true) { System.out.println(Thread.currentThread().getName()); } } }
使用Runnable接口创建多线程
Thread构造方法中有 Thread(Runnable target),Runnable他是一个接口类,该接口只有一个run方法。那么继承这个接口并实现他,就能实现多线程。使用Runnable接口来创建多线程比继承Thread类来创建多线程要更灵活,更好!但是只使用Runnable,就不能用setName方法。
public class test9 { public static void main(String[] args) { Thread t1 = new Thread(new TestThread()); t1.start(); while(true) { System.out.println(Thread.currentThread().getName()); } } } class TestThread implements Runnable { public void run() { while(true) { System.out.println(Thread.currentThread().getName()); } } }
两种多线程方式的对比
通过一个售票例子来对比两种线程,我们希望100张票在四个售票点卖。先试着用继承Thread来实现创建多线程方式试试。
public class test9 { public static void main(String[] args) { TestThread t1 = new TestThread(); t1.start(); TestThread t2 = new TestThread(); t2.start(); TestThread t3 = new TestThread(); t3.start(); TestThread t4 = new TestThread(); t4.start(); } } class TestThread extends Thread { int tickets = 100; public void run() { while(true) { if(tickets>0) System.out.println(Thread.currentThread().getName() + "还有多少张:"+ tickets--); } } }
运行的结果并不是我们想像的那样,发现他是四个售票点各卖100张票,我们希望的是100张票共用在四个售票点卖。那么应该怎么实现,显然用第一种多线程的方式难以实现,那么我们用第二种创建多线程的方式来实现。为了能清楚的看执行顺序,加一下Thread.sleep. 让线程小睡一会!
public class test9 { public static void main(String[] args) { TestThread t = new TestThread(); new Thread(t).start(); new Thread(t).start(); new Thread(t).start(); new Thread(t).start(); } } class TestThread implements Runnable { int tickets = 100; public void run() { while(true) { try{Thread.sleep(10);}catch(Exception e){} if(tickets>0) System.out.println(Thread.currentThread().getName() + "还有多少张:"+ tickets--); } } }
使用setDaemon设置为后台线程(当一个程序为前台线程时,就算运行到main结束了,程序也要等前台线程结束了他才结束。但设置为后台线程,则是main函数结束了,那么程序就结束了。)上面的售票例子,发现运行到最后main函数程序并没有结束,对于JAVA程序来说,只要还有一个前台线程在运行,那么程序就不会结束。如果想让上面的程序要卖完售票后就结束,可以设置他为后台线程。
Class ThreadDemo1 { Public static void main(String[] args) { Thread tt = new TestThread(); tt.setDaemon(true); tt.start(); } } Class TestThread extends Thread { Public void run() { Whlile(true) { System.out.println(“run”+ Thread.currentThread().getName()); } } }
联合 线程JOIN
什么是联合线程?当前线程邀请调用方法的线程优先执行,在调用方法的线程执行结束之前,当前线程不能再次执行。运行下面程序看到一开始Thread和Main两个线程一开始交替运行,后来只有Thread一个在运行。产生这样的原因是因为调用了JOIN。(使得Thread和MAIN合并成一个线程,并且Thread线程排在MAIN线程的前面,所以Thread线程没有结束前就不会执行到MAIN线程)
public class test9 { public static void main(String[] args) { Thread t = new Thread(new TestThread()); t.start(); int i=0; while(true) { if(i==100) { try{ t.join();} catch(Exception e){} } try{ Thread.sleep(10);} catch(Exception e){} System.out.println(Thread.currentThread().getName() + i++); } } } class TestThread implements Runnable { public void run() { int i = 0; while(true) { try{ Thread.sleep(10);} catch(Exception e){} System.out.println(Thread.currentThread().getName() + i++); } } }
看一下运行的结束:
参考资料来源于:《JAVA就业培训教程》、《JAVA大学实用教程》