一、线程创建
1、继承Thread类
首先,自定义线程类继承THread类;其次,重写run方法,编写线程执行体;最后,创建线程对象并调用start()方法启动线程。但值得注意的是,线程并不一定会立刻执行,而是由CPU进行调度执行。继承Thread类实现线程创建的具体代码如下所示:
//自定义线程继承Thread类 public class thread_Thread extends Thread { //重写run()方法编写线程执行体 public void run() { for (int i = 0; i<3; i++) { System.out.println("listening music---" + i); } } //创建线程对象,调用start()方法启动线程 public static void main(String[] args) { thread_Thread thread = new thread_Thread() ; thread.start(); for (int i = 0; i<3; i++) { System.out.println("playing game---" + i); } } }
上述程序运行结果如下所示:
2、实现Runnable接口
首先,定义一个类实现接口Runnable;其次,实现run()方法并编写线程执行体;最后,创建线程对象并调用start()方法启动线程。其具体代码实现如下所示:
public class thread_Runable_1 implements Runnable { public void run() { for (int i = 0; i < 5; i++) { System.out.println("runnable接口" + i); } } public static void main(String[] args) { //创建实现对象 thread_Runable_1 thread_Runable_1 = new thread_Runable_1(); //创建代理类对象 //Thread thread = new Thread(thread_Runable_1); //thread.start(); new Thread(thread_Runable_1).start(); } } class test implements Runnable{ public void run(){ } }
上述程序运行结果如下所示:
实现Runnable接口时具备多线程能力可以有效地避免单线程的局限性,也能够便于一个对象被单个线程使用,其具体实现代码如下所示:
public class thread_Runable_2 implements Runnable{ //多个线程同时操作一个对象(买火车票) private int ticketnum = 10; public void run(){ while (true){ if (ticketnum <= 0){ break; } System.out.println(Thread.currentThread().getName() + "拿到了第" + ticketnum-- + "张票"); } } public static void main(String[] args) { thread_Runable_2 thread_Runable_2 = new thread_Runable_2(); new Thread(thread_Runable_2,"老师").start(); new Thread(thread_Runable_2,"同学").start(); new Thread(thread_Runable_2,"黄牛").start(); } }
上述程序的执行结果如下图所示:
值得注意的是,多个线程操作同一资源的情况下则容易产生线程的不安全现象,还可能导致数据紊乱。
3、实现Callable接口
首先,需要创建一个实现Callable
的实现类。再实现call()
方法,将此线程需要执行的操作声明在call()
中;其次,需要创建Callable
接口实现类的对象,并将此Callable
接口实现类的对象作为传递到FutureTask
构造器中,创建FutureTask
的对象;最后,将FutureTask
的对象作为参数传递到Thread
类的构造器中,创建Thread
对象,并调用start()
方法。其具体实现代码如下所示:
import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; public class thread_Callable { public static void main(String[] args){ CallableThread callableThread = new CallableThread(); FutureTask futureTask = new FutureTask(callableThread); Thread t1 = new Thread(futureTask); t1.start(); try { //get()方法的返回值即为FutureTask构造器参数Callable实现类重写的call()的返回值 Object sum = futureTask.get(); System.out.println(sum); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } } class CallableThread implements Callable { @Override public Object call() throws Exception { int sum = 0; for (int i = 0; i <= 10; i++) { if (i % 2 ==0){ System.out.println(i); sum += i; } } return sum; } }
代码运行结果如下所示:
住的注意的是,与使用Runnable
相比,Callable
功能更强大;相比于run()
方法,call()方法则可以获取返回值,除此之外,call()
方法可以抛出异常,被外面的操作捕获,获取异常的信息。Callable
支持泛型的返回值,但需要借助FutureTask
类,比如获取返回结果。
Future
接口可以对具体Runnable
、Callable
任务的执行结果进行取消、查询是否完成、获取结果等操作。另外,FutureTask
是Future
接口的唯一实现类。且当FutureTask
同时实现了Runnable
、Future
接口时,它既可以作为Runnable
被线程执行,也可以作为Future
得到Callable
的返回值。
二、线程状态
线程状态主要划分为创建状态(new)、就绪状态(ready)、阻塞状态(waiting)、运行状态(running)和死亡状态(dead)五种。
注意事项:
①程序运行至“Thread t = new Thread()”时线程对象实现创建后即进入创建状态。
②当调用start()方法时线程进入就绪状态且不立刻调度执行。
③当调用sleep、wait或同步锁定是,线程进入阻塞状态,直至阻塞时间结束才重新进入就绪状态并等待CPU调度执行。
④只有进入运行状态线程才真正开始执行线程体的代码块。
⑤线程中断或结束,线程一旦进入死亡状态就无法再次启动。
三、线程方法
一般情况下,线程存在开始执行、休眠、礼让、更改优先级、插队等方法,其调用的函数情况具体如下所示:
public class Thread_stop implements Runnable{ //设置标志位 private boolean flag = true; public void run(){ int i = 0; while (flag) { System.out.println("run……thread" + i++); } } //设置公开方法停止线程,转换标志位 public void stop(){ this.flag = false; } public static void main(String[] args) { //调用stop方法切换标志位进而停止线程 Thread_stop Thread_stop = new Thread_stop(); new Thread(Thread_stop).start(); for (int i = 0; i < 4; i++){ System.out.println("thread……" + i); if(i == 3){ Thread_stop.stop(); System.out.println("线程停止"); } } } }
2、进程休眠sleep()
sleep()可以模仿网络延时、倒计时等。
每个对象都有一个锁,sleep不会释放锁。
sleep()存在异常InterruptedException()。
sleep()时间到达后线程就可以进入就绪状态。
利用进程休眠方法sleep()可以进行模拟时延操作,进而实现模拟抢票。其具体实现代码如下所示:
public class Thread_sleep_1 implements Runnable{ //票数 private int ticketNums = 7; @Override public void run() { while (true) { if (ticketNums <= 1){ break; } //模拟延时 try { Thread.sleep(100); } catch (Exception e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "--->拿到了第" + ticketNums-- + "票"); } } public static void main(String[] args) { Thread_sleep_1 Thread_sleep_1 = new Thread_sleep_1(); new Thread(Thread_sleep_1,"老师").start(); new Thread(Thread_sleep_1,"同学").start(); new Thread(Thread_sleep_1,"黄牛").start(); } }
上述代码的运行结果如下所示:
利用进程休眠方法sleep()也可以实现模拟倒计时操作,其具体实现代码如下所示:
public class Thread_sleep_2 { public static void main(String[] args) { try{ tendown(); } catch (InterruptedException e) { e.printStackTrace(); } } //模拟倒计时 public static void tendown() throws InterruptedException { int num = 10; while (true){ Thread.sleep(1000); System.out.println("倒计时:第" + num-- + "秒"); if (num <= 0){ break; } } } }
上述代码的运行结果如下所示:
3、进程礼让yield()
线程礼让即暂停当前正在执行中的线程,将线程有运行状态转化成就绪状态而不是进入阻塞状态。线程礼让揖让CPU重新调度线程,但礼让未必能够成功。线程礼让程序具体代码如下所示:
public class Thread_yield { public static void main(String[] args) { MyYield myYield = new MyYield(); new Thread(myYield,"A").start(); new Thread(myYield,"B").start(); } } class MyYield implements Runnable { public void run() { System.out.println(Thread.currentThread().getName()+"线程开始执行"); Thread.yield();//礼让 System.out.println(Thread.currentThread().getName()+"线程停止执行"); } }
上述程序运行结果如下所示:
4、线程合并join()
join合并线程相当于插队,插队后其他线程进入阻塞状态,待到该线程执行结束后在执行其他线程,其他线程的优先级不变。其具体实现代码如下所示:
public class Thread_join implements Runnable { public void run() { for (int i = 0; i < 3; i++) { System.out.println("我是VIP,我想先执行"+i); } } public static void main(String[] args) throws InterruptedException { //启动线程 Thread_join threadjoin = new Thread_join(); Thread thread = new Thread(threadjoin); thread.start(); //主线程 for (int i = 0; i < 7; i++) { if (i == 5) { thread.join(); } System.out.println("mian" +i ); } } }
上述代码的运行结果如下所示:
5、查看线程状态state
Thread.State线程可处于以下六种状态中的任意一种:
New:尚未其中的线程所处状态。
Terminated:一退出线程所处于状态。
Runnable:在Java虚拟机中执行线程所处状态。
Blocked:被阻塞而等待监视器锁定的线程所处状态。
Waiting:正在等待其他线程执行特定功能所处于的状态。
Timed_waiting:正在等待其他线程执行动作到执行等待时间所处状态。
线程状态查看的具体代码如下所示:
public class Thread_state { public static void main(String[] args) { for (int i = 0; i < 1; i++) { Thread thread = new Thread(()->{ try { Thread.sleep(1000); } catch (InterruptedException e) { throw new RuntimeException(e); } }); //开始观察状态 Thread.State state = thread.getState(); System.out.println(state); //NEW //观察启动后 thread.start(); state = thread.getState(); System.out.println(state); while (state != Thread.State.TERMINATED){ try { Thread.sleep(100); state = thread.getState(); System.out.println(state); } catch (InterruptedException e) { throw new RuntimeException(e); } } //thread.start(); } } }
上述代码运行结果如下所示:
6、线程优先级
Java中会提供一个线程调度器对程序启动后进入就绪状态的所有线程进行监控,线程调度器会按照优先级来决定线程的调度顺序。此外,线程的优先级用数字表示范围在1到10之间,即:Thread.MIN_PRIORITY=1、 Thread.NORM_PRIORITY=5、Thread.MAX_PRIORITY=10。其具体实现代码如下所示:
public class Thread_priority { public static void main(String[] args) { System.out.println(Thread.currentThread().getName()+"-->"+Thread.currentThread().getPriority()); MyPriority myPriority = new MyPriority(); Thread t1 = new Thread(myPriority); Thread t2 = new Thread(myPriority); Thread t3 = new Thread(myPriority); Thread t4 = new Thread(myPriority); Thread t5 = new Thread(myPriority); Thread t6 = new Thread(myPriority); Thread t7 = new Thread(myPriority); Thread t8 = new Thread(myPriority); //设置线程优先级并启动线程 t1.start(); t2.setPriority(1); t2.start(); t3.setPriority(Thread.MIN_PRIORITY); System.out.println(t2.getPriority()); t3.start(); t4.setPriority(10); t4.start(); t5.setPriority(8); t5.start(); t6.setPriority(Thread.MAX_PRIORITY); t6.start(); t7.setPriority(4); t7.start(); t8.setPriority(6); t8.start(); } } class MyPriority implements Runnable{ public void run() { System.out.println(Thread.currentThread().getName()+"-->"+Thread.currentThread().getPriority()); } }
其中getPriority()可获取线程优先级,setPriority()可设置线程优先级。
上述代码的运行结果如下所示:
7、守护线程daemon
线程主要可以划分为用户线程和守护线程两种,虚拟机必须要确保用户线程执行完整却不需要保证守护线程执行完毕,如后台常见的操作日志、监控内存、垃圾回收等。其具体实现代码如下所示:
public class Thread_daemon { public static void main(String[] args) { God god = new God(); You you = new You(); Thread thread = new Thread(god); //默认为false,代表为用户线程 thread.setDaemon(true); thread.start(); new Thread(you).start(); } } class God implements Runnable{ public void run() { while (true){ System.out.println("上帝守护着你"); } } } class You implements Runnable{ public void run() { for (int i = 0; i < 10; i++) { System.out.println("你每天都过得很开心"+i); } System.out.println("你没了"); } }
上述代码的运行结果如下所示(仅部分运行结果):
原文地址:http://www.cnblogs.com/Auion-idiot/p/16929631.html