后台线程
/**
* Daemon后台线程
* 功能:如果main线程结束 由main线程启动的线程也随之结束
* 当循环结束后 线程跟着结束
*
*/
public class TestDaemon extends Thread{
@Override
public void run() {
while(true){
System.out.println("-------------------"+this.getName()+"-----------------------");
}
}
public static void main(String[] args) {
//创建线程
TestDaemon td=new TestDaemon();
td.setDaemon(true);//设置后台线程 必须在start之前
td.start();
for (int i = 0; i <100; i++) {
System.out.println("---------------main-------------------");
}
}
}
Interrupt 中断线程
import java.io.IOException;
/**
* 3.使用Interrupt中断线程
* 只能中断正在休眠的线程或调用Interrupt方法后
* 子线程执行了抛出InterruptedException异常
* 比如:sleep() wait() join()
* @author liuxin
* InterruptedException e
*/
public class TestInterrupt {
public static void main(String[] args) throws IOException {
//第一种方式
//创建一个线程对象
InterrupThread it=new InterrupThread();
//启动线程
it.start();
System.out.println("输入任意字符中断InterrupThread线程:");
System.in.read();
it.interrupt();
System.out.println("主线程结束");
// 第二种方式
// 创建一个线程对象
// InterrupThread2 it=new InterrupThread2();
// it.start();
// it.interrupt();
// System.out.println("主线程结束");
}
}
class InterrupThread extends Thread{
@Override
public void run() {
try {
System.out.println("正在睡觉");
Thread.sleep(10000);
System.out.println("睡醒了");
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("被打醒的");
}
}
}
class InterrupThread2 extends Thread{
@Override
public void run() {
for (int i = -9999; i <9999 ; i++) {
for (int j = -9999; j < 9999; j++) {
}
}
try {
System.out.println("正在睡觉");
Thread.sleep(10000);
System.out.println("睡醒了");
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("被打醒的");
}
}
}
第一种方法输出的结果
输入任意字符中断InterrupThread线程:
正在睡觉
睡醒了
1
主线程结束
第二种方法输出的结果
主线程结束
正在睡觉
java.lang.InterruptedException: sleep interrupted
被打醒的
at java.lang.Thread.sleep(Native Method)
at com.qf.test.thread.control.InterrupThread2.run(TestInterrupt.java:59)
线程阻塞
/**
* Join ()
阻塞指定线程等到另一个线程完成以后再继续执行
注意:一定加载 start()之后
* @author liuxin
*
*/
public class TestJoin extends Thread{
public TestJoin() {
super();
}
public TestJoin(String name) {
super(name);
}
@Override
public void run() {
for (int i = 1; i < 10; i++) {
System.out.println(i+"------"+i+"--------->"+this.getName()+"<---------------");
}
}
public static void main(String[] args) {
//main线程
for (int i = 1; i < 20; i++) {
System.out.println("----------------------main--------------------------");
if(i==5){
TestJoin t=new TestJoin("程咬金");
t.start();//
try {
t.join();//主线程
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
输出结果
----------------------main--------------------------
----------------------main--------------------------
----------------------main--------------------------
----------------------main--------------------------
----------------------main--------------------------
1------1--------->程咬金<---------------
2------2--------->程咬金<---------------
3------3--------->程咬金<---------------
4------4--------->程咬金<---------------
5------5--------->程咬金<---------------
6------6--------->程咬金<---------------
7------7--------->程咬金<---------------
8------8--------->程咬金<---------------
9------9--------->程咬金<---------------
----------------------main--------------------------
----------------------main--------------------------
----------------------main--------------------------
----------------------main--------------------------
----------------------main--------------------------
----------------------main--------------------------
----------------------main--------------------------
----------------------main--------------------------
----------------------main--------------------------
----------------------main--------------------------
----------------------main--------------------------
----------------------main--------------------------
----------------------main--------------------------
----------------------main--------------------------
线程睡眠
/**
* 模拟:时钟 秒表:09:12:23
* @author liuxin
* sleep的作用:
* 阻塞当前线程,指定的时间后解除阻塞
* 在此时间内即使CPU是空闲的线程也不会解除阻塞
*
*/
public class TestSleep2 {
public static void main(String[] args) {
DateFormat sdf=new SimpleDateFormat("hh:mm:ss");
while(true){
Date now=new Date();
String strdate = sdf.format(now);
System.out.println(strdate);
//sleep 1秒
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
输出结果
04:30:29
04:30:30
04:30:31
04:30:32
04:30:33
04:30:34
04:30:35
04:30:36
04:30:37
04:30:38
04:30:39
线程优先级
/**
*1.如何看某个线程的级别
* 对象.getPriority()
*2 如何设置优先级
* 对象.setPriority(7);
* 3.优先级的级别
* public final static int MIN_PRIORITY = 1;
* public final static int NORM_PRIORITY = 5;
* public final static int MAX_PRIORITY = 10;
* @author liuxin
*之前的程序都是单线程的:线程默认main
*/
public class TestThread1 {
public static void main(String[] args) {
Thread.currentThread().setName("兔子线程");
//乌龟线程
TortoiseThread tt=new TortoiseThread();
//调用方法
tt.setName("乌龟线程");
tt.setPriority(7);
tt.start();//启动线程 裁判手里的枪 自动调用run()方法
//兔子线程
while(true){
System.out.println("-------------兔子领先了----------"+Thread.currentThread().getName()+"优先级:"+Thread.currentThread().getPriority());
}
}
}
TortoiseThread类
public class TortoiseThread extends Thread{
//乌龟线程
/**
* 线程体
*/
@Override
public void run() {
// this.setName("乌龟线程");
while(true){
System.out.println("乌龟领先了--------"+this.getName()+"优先级:"+this.getPriority());
}
}
}
线程的创建
/**
* 功能:
* 龟兔赛跑
* 龟兔赛跑的实质:
* 两个线程交替获得CPU,CPU来执行代码
* 总结
* 1.如何创建线程
* public class TortoiseThread extends Thread{
* public void run(){
*
* }
* }
* 2.如何启动线程
* TortoiseThread tt=new TortoiseThread();
* tt.start();//启动线程 裁判手里的枪 自动调用run()方法
* 3.常用方法
* run() 线程体
* this.getName()得到线程的名字
* tt.setName("乌龟线程");设置线程名字
* Thread.currentThread()得到当前线程
* @author liuxin
*之前的程序都是单线程的:线程默认main
*/
public class TestThread1 {
public static void main(String[] args) {
Thread.currentThread().setName("兔子线程");
//乌龟线程
TortoiseThread tt=new TortoiseThread();
//调用方法
// tt.run();
tt.setName("乌龟线程");
tt.start();//启动线程 裁判手里的枪 自动调用run()方法
//兔子线程
while(true){
System.out.println("-------------兔子领先了----------"+Thread.currentThread().getName());
}
}
}
public class TortoiseThread extends Thread{
//乌龟线程
/**
* 线程体
*/
@Override
public void run() {
// this.setName("乌龟线程");
while(true){
System.out.println("乌龟领先了--------"+this.getName());
}
}
}
继承接口方式
/**
* 功能: 乌龟赛跑
* 总结:
* 1.创建线程的第二种方式
* public class TortoiseRunable implements Runnable {
* public void run(){
*
* }
* }
* 2.如何启动线程
* TortoiseRunable tr=new TortoiseRunable();
* Thread th=new Thread(tr);
* th.start();//启动线程 jvm调用 乌龟线程的run()方法
* 3.两种方式的区别
* 1.继承Thread类
* 优点:编程简单
* 缺点:已经继承一个Thread类 无法继承其他类
* 2.实现Runable接口
* 优点:可以继承其他类,最主要原因:多个线程共享同一变量
* 缺点:编程稍微复杂
*
* 如果多个线程共享同一资源:采用实现接口
* @author liuxin
* 1206 购票 票数固定 1000 998
* 1 2 3 4
*/
public class TestThread2 {
public static void main(String[] args) {
Thread.currentThread().setName("兔子线程");//main
//实例乌龟线程
TortoiseRunable tr=new TortoiseRunable();
Thread th=new Thread(tr);
th.setName("乌龟线程");
th.start();//启动线程 jvm调用 乌龟线程的run()方法
while(true){
System.out.println("----------兔子领先了"+Thread.currentThread().getName());
}
}
}
引用接口的方法
public class TortoiseRunable implements Runnable {
/**
* 线程体
*/
@Override
public void run() {
while(true){
System.out.println("乌龟领先了"+Thread.currentThread().getName());
}
}
}
调用接口方式共享资源
package com.qf.test.thread5;
/**
* 创建四个窗口 卖票
* @author liuxin
*
*/
public class TestThread {
public static void main(String[] args) {
//创建四个窗口 卖票
TicketRunable tr=new TicketRunable();//run()售票 200
//创建四个线程
Thread th1=new Thread(tr);//Runable r= new TicketRunable();//run()售票 200
Thread th2=new Thread(tr);
Thread th3=new Thread(tr);
Thread th4=new Thread(tr);//新生状态
//启动线程
th1.start();//就绪状态
th2.start();
th3.start();
th4.start();
}
}
package com.qf.test.thread5;
public class TicketRunable implements Runnable {
private int ticNum=200;
@Override
public void run() {
while(ticNum>0){
System.out.println(Thread.currentThread().getName()+"窗口卖出了第"+ticNum--+"张票");
//票数减一
// ticNum--;
}
}
}