继承Thread
public class MyThread extends Thread {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("哈哈哈"+i);
}
}
}
public class Test {
public static void main(String[] args) {
MyThread m = new MyThread();
m.start();
for (int i = 0; i < 10; i++) {
System.out.println("aaa"+i);
}
}
}
实现Runnable接口
public class MyRunnable implements Runnable {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("窗前明月光"+i);
}
}
}
/**
* 多线程技术
*实现Runnable与继承Thread相比有如下优势:
* 1.通过创建任务,然后给线程分配的方式来实现多线程,更适合多个线程同时执行相同任务的情况
* 2.可以避免单继承所带来的局限性
* 3.任务与线程本身是分离的,提高了程序的健壮性
*/
public class Test {
public static void main(String[] args) {
//实现Runnable
//1.创建一个任务对象
MyRunnable r = new MyRunnable();
//2.创建一个线程,并为其分配一个任务
Thread t = new Thread(r);
//3.执行这个线程
t.start();
for (int i = 0; i < 10; i++) {
System.out.println("疑似地上霜"+i);
}
}
}
线程中断
public class Test {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new MyRunnable());
t1.start();
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName()+":"+i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//给线程t1添加中断标记
t1.interrupt();
}
static class MyRunnable implements Runnable {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName()+":"+i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
//e.printStackTrace();
return;
}
}
}
}
}
守护线程
/**
* 多线程技术
* 线程:分为守护线程和用户线程
* 用户线程:当一个进程不包含任何的存活的用户线程时,进行结束
* 守护线程:守护用户线程的,当最后一个用户线程结束时,所有守护线程自动死亡
*/
public class Test {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new MyRunnable());
//设置t1为守护线程
t1.setDaemon(true);
t1.start();
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName()+":"+i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
static class MyRunnable implements Runnable {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName()+":"+i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
//e.printStackTrace();
return;
}
}
}
}
}
线程安全
同步代码块
public class Test {
public static void main(String[] args) {
Runnable run = new Ticket();
new Thread(run).start();
new Thread(run).start();
new Thread(run).start();
}
static class Ticket implements Runnable {
//票数
private int count = 10;
//定义一个锁的对象
private Object o = new Object();
@Override
public void run() {
while (true) {
//把需要执行的代码锁起来
synchronized (o) {
if (count > 0) {
System.out.println("开始卖票:");
//睡眠1s
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
count--;
System.out.println(Thread.currentThread().getName() + "出票成功,余票:" + count);
} else {
break;
}
}
}
}
}
}
同步方法
public class Test {
public static void main(String[] args) {
Runnable run = new Ticket();
new Thread(run).start();
new Thread(run).start();
new Thread(run).start();
}
static class Ticket implements Runnable {
//票数
private int count = 10;
//定义一个锁的对象
private Object o = new Object();
@Override
public void run() {
while (true) {
//把需要执行的代码锁起来
boolean flag = sale();
if (!flag) {
break;
}
}
}
public synchronized boolean sale() {
if (count > 0) {
System.out.println("开始卖票:");
//睡眠1s
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
count--;
System.out.println(Thread.currentThread().getName() + "出票成功,余票:" + count);
return true;
}
return false;
}
}
显示锁Lock
public class Test {
public static void main(String[] args) {
Runnable run = new Ticket();
new Thread(run).start();
new Thread(run).start();
new Thread(run).start();
}
static class Ticket implements Runnable {
//票数
private int count = 10;
//显示锁
private Lock l = new ReentrantLock();
@Override
public void run() {
while (true) {
//把需要执行的代码锁起来
l.lock();
if (count > 0) {
System.out.println("开始卖票:");
//睡眠1s
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
count--;
System.out.println(Thread.currentThread().getName() + "出票成功,余票:" + count);
}else{
break;
}
l.unlock();
}
}
}
}
缓存线程池
缓存线程池.
* (长度无限制)
* 执行流程:
* 1. 判断线程池是否存在空闲线程
* 2. 存在则使用
* 3. 不存在,则创建线程 并放入线程池, 然后使用
public class Demo03 {
public static void main(String[] args) {
ExecutorService service = Executors.newCachedThreadPool();
//指挥线程池中执行新的任务
service.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"床前明月光");
}
});
service.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"床前明月光");
}
});
service.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"床前明月光");
}
});
//睡眠一秒钟测试下面代码是不是调用线程池中空闲的线程
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
service.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"床前明月光");
}
});
}
}
定长线程池
* 定长线程池.
* (长度是指定的数值)
* 执行流程:
3. 单线程线程池
4. 周期性任务定长线程池
* 1. 判断线程池是否存在空闲线程
* 2. 存在则使用
* 3. 不存在空闲线程,且线程池未满的情况下,则创建线程 并放入线程池, 然后使用
* 4. 不存在空闲线程,且线程池已满的情况下,则等待线程池存在空闲线程
public class Demo04 {
public static void main(String[] args) {
//线程池中有两个线程
ExecutorService service = Executors.newFixedThreadPool(2);
service.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+":1");
//为了测试睡眠三秒
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
service.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+":2");
//为了测试睡眠三秒
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
service.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+":3");
}
});
}
}
单线程线程池
单线程线程池.
* 执行流程:
* 1. 判断线程池的那个线程是否空闲
* 2. 空闲则使用
* 4. 不空闲,则等待池中的单个线程空闲后使用
public class Demo05 {
public static void main(String[] args) {
ExecutorService service = Executors.newSingleThreadExecutor();
service.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+":1");
}
});
service.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+":1");
}
});
service.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+":1");
}
});
}
}
周期定长线程池
public class Demo06 {
public static void main(String[] args) {
ScheduledExecutorService service = Executors.newScheduledThreadPool(2);
/*
定时执行一次
参数1:定时执行任务
参数2:时长数字
参数3:时长数字的时间单位,TimeUnit的常量指定
*/
/* service.schedule(new Runnable() {
@Override
public void run() {
System.out.println("1");
}
},3, TimeUnit.SECONDS);
*/
/*
周期性执行任务
参数1:任务
参数2:延迟时长数字(第一次执行在什么时间以后)
参数3:周期时长数字(每隔多久执行一次)
参数4:时长数字的单位
*/
service.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
System.out.println(1);
}
},5,1,TimeUnit.SECONDS);//5s中之后开始执行,每个1s执行一次
}
}