多线程
线程:Thread
单线程:单个任务,一个执行路径,一个顺序流。
多线程:多个任务执行,多个路径执行,多个顺序流
三高网站:高性能、高可用、高并发。
多线程的优点:效率高。
串行:在同一时间内,多个任务快速串行——》多线程
并行:在同一个时间段内多个任务同时执行。
创建线程的三种方式
继承Thread,重写run()方法
public class ThreadDemo01 extends Thread{
public static void main(String[] args) throws InterruptedException {
ThreadDemo01 threadDemo01=new ThreadDemo01();
threadDemo01.start();
for(int i=0;i<=10;i++){
System.out.println("跑步");
Thread.sleep(50);
}
}
@Override
public void run() {
for (int i=0;i<=20;i++){
System.out.println( "吃饭");
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
实现Runnable,重写run()方法,方法内部定义线程体
class ThreadDemo02 implements Runnable{
public static void main(String[] args) throws InterruptedException {
ThreadDemo02 threadDemo02=new ThreadDemo02();
new Thread(threadDemo02).start();
for(int i=0;i<=10;i++){
System.out.println("做梦");
Thread.sleep(50);
}
}
@Override
public void run() {
for (int i=0;i<=20;i++){
System.out.println( "睡觉");
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
通过Callable接口call() 定义线程体
public class ThreadDemo05 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
Match2 match = new Match2();
//通过线程池 固定大小线程池2个 static ExecutorService newFixedThreadPool(int nThreads)
//1.创建执行服务
ExecutorService server = Executors.newFixedThreadPool(2);
//2.提交任务 <T> Future<T> submit(Callable<T> task) 提交值返回任务以执行并返回表示任务的挂起结果的Future。
Future<Integer> f1 = server.submit(match);
Future<Integer> f2 = server.submit(match);
//3.获取结果
Integer result1 = f1.get();
Integer result2 = f2.get();
System.out.println(result1);
System.out.println(result2);
//4.结束服务
server.shutdown();
}
}
//比赛
class Match2 implements Callable<Integer> {
//结束标识
private String winner; //记录赢的人的名字
/*
可以抛出异常
*/
@Override
public Integer call() throws InterruptedException {
//i作为步数
for(int i=1;i<=100;i++){
//是否为兔子
System.out.println(Thread.currentThread().getName()+"正在跑第"+i+"步");
if("兔子".equals(Thread.currentThread().getName()) && i%20==0){
Thread.sleep(20);
}
//结束判断
if(checkOver(i)){
return i;
}
}
return null;
}
//结束的条件判定 返回值: true结束 false不结束
public boolean checkOver(int steps){
boolean flag = false;
//有人赢了
if(winner != null){
return true;
}
//自己赢了
if(steps==100){
winner = Thread.currentThread().getName();
return true;
}
return false;
}
}
练习题
龟兔赛跑:
乌龟一直不停的再跑
兔子每次跑20步休息两秒
class ThreadDemo04 implements Runnable {
int i=0;
String string;
@Override
public void run() {
while (true){
i++;
System.out.println(Thread.currentThread().getName()+"跑了"+i+"步");
if ("兔子".equals(Thread.currentThread().getName())&&i%20==0){
try {
Thread.sleep(15);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if(flg(i)){
break;
}
}
}
public boolean flg(int k){
boolean flge=false;
if (string!=null){
return true;
}
if (k==100){
string=Thread.currentThread().getName();
return true;
}
return false;
}
public static void main(String[] args) {
ThreadDemo04 threadDemo04=new ThreadDemo04();
Thread thread01=new Thread(threadDemo04,"乌龟");
Thread thread02=new Thread(threadDemo04,"兔子");
thread01.start();
thread02.start();
}
}
Sleep线程睡眠****
public class SleepText {
public static void main(String[] args) {
Thread thread=new Thread(){
@Override
public void run() {
int i=10;
while (i>=0){
try {
sleep(1000);
System.out.println("时间结束还有"+i--+"秒");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("时间到");
}
};
thread.start();
}
}
yield
礼让线程 给了其他线程更多的执行机会,但是不能决定是否其他线程一定执行,要看cpu的调度
public class YieldDemo02 implements Runnable{
public static void main(String[] args) {
YieldDemo02 yd = new YieldDemo02();
new Thread(yd,"年轻人").start();
new Thread(yd,"老大爷").start();
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"开始执行");
System.out.println(Thread.currentThread().getName()+"礼让");
Thread.yield(); //礼让
System.out.println(Thread.currentThread().getName()+"收礼");
}
}
Join:加入线程(插队线程)
Join()等待插队线程执行完毕,当前线程才能继续执行
Join(ms)最多只等待xxm的时间。
class Join1 implements Runnable{
private Object Join2;
@Override
public void run() {
System.out.println("想抽烟");
System.out.println("喊儿子去买");
System.out.println("给钱");
Thread thread=new Thread(new Join2());
thread.start();
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("接过煊赫门");
System.out.println("开始抽");
}
}
class Join2 implements Runnable{
@Override
public void run() {
int i=10;
System.out.println("儿子拿钱");
while (i>=0) {
try {
Thread.sleep(1000);
System.out.println("来回花了" + i-- + "秒");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("买煊赫门");
System.out.println("给父亲");
}
}
class Join3 {
public static void main(String[] args) {
Thread thread= new Thread(new Join1());
thread.start();
}
}
获取当前线程的状态:观察线程的运行周期
Thread类中提供一个属性:getState()获取一个线程当前的一个状态
返回一个Thread.State枚举类型
class State{
public static void main(String[] args) {
Thread thread=new Thread(){
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"-->"+getState());
for (int i=0;i<10;i++){
try {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName()+"-->"+getState());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+"-->"+getState());
}
};
System.out.println(Thread.currentThread().getName()+"-->"+thread.getState());
thread.start();
System.out.println(Thread.currentThread().getName()+"-->"+thread.getState());
while(true){
System.out.println(thread.getState());
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
//当th1执行完毕进入终止状态结束打印
if(thread.getState().equals(Thread.State.TERMINATED)){
System.out.println(thread.getState());
break;
}
}
}
}
线程优先级:
每一个线程都存在优先级:优先级执行的可能性
优先级只能放大执行的机会,不代表一定先执行或者后执行
class YouXianJ{
public static void main(String[] args) {
Thread thread=new Thread(){
@Override
public void run() {
System.out.println(1);
}
};
Thread thread2=new Thread(){
@Override
public void run() {
System.out.println(5);
}
};
Thread thread3=new Thread(){
@Override
public void run() {
System.out.println(10);
}
};
//设置优先级
thread.setPriority(1);
thread2.setPriority(5);
thread3.setPriority(10);
thread.start();
thread2.start();
thread3.start();
}
}
中断线程
void interrupt() 为一个线程添加一个中断标识。
static boolean interrupted() interrupted方法判断当前线程已经被添加过中断标识(是否当前线程调用过 interrupt()方法).同时复位中断标识。
boolean isInterrupted() 判断线程是否添加过中断标识,但是不会清楚这个标识。
以上三个方法都不能实现线程的终止,只是添加|判断标识,配合break,return…一起使用。
如果一个线程执行完毕,会自动复位|清除终止标识
public class InterruptDemo07 {
public static void main(String[] args) {
Thread th = new Thread(()->{
int i = 1;
while(true){
System.out.println("我是th线程"+i++);
if(Thread.interrupted()==true){
System.out.println("结束");
System.out.println("结束之前最后判断状态"+Thread.currentThread().isInterrupted());
break;
}
}
});
th.start();
System.out.println(th.isInterrupted());
th.interrupt();
for(int i=1;i<=10;i++){
System.out.println(th.isInterrupted());
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
守护线程
守护线程与用户线程区别:
守护线程,就是用来守护用户线程的,当用户线程执行完毕,守护线程会直接结束。
创建的线程默认用户线程。
垃圾回收器就是一个典型的守护线程。
如何设置一个线程为守护线程: void setDaemon(boolean on) 将此线程标记为 daemon线程或用户线程。 true->守护线程 false->用户线程。
先设置守护线程,然后再start()。
public class OtherDemo06 {
public static void main(String[] args) {
Thread th = new Thread(()->{
int i = 1;
while(true){
System.out.println("我是守护线程"+i++);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
//设置守护线程
th.setDaemon(true);
//开启线程
th.start();
//主线程默认用户线程
for(int i=1;i<=20;i++){
System.out.println("main用户线程"+i);
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
线程安全
同步方法
public class SynchonzedTexte implements Runnable {
int tickets=100;
@Override
//同步方法syncharonized修饰
public synchronized void run() {
while (true) {
//A B C
if (tickets <= 0) {
break;
}
//A B C
System.out.println(Thread.currentThread().getName() + "正在购买第" + tickets-- + "张票");
//模拟网络延迟
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
SynchonzedTexte synchonzedTexte = new SynchonzedTexte();
//创建3个线程
new Thread(synchonzedTexte,"zhangsan").start();
new Thread(synchonzedTexte,"lisi").start();
new Thread(synchonzedTexte,"wangwu").start();
}
}
同步块:类.class
//synchronized(类.class){}
class SynchonzedTexte01 implements Runnable {
int tickets = 100;
@Override
public void run() {
while (true) {
synchronized (SynchonzedTexte01.class) {
if (tickets <= 0) {
break;
}
System.out.println(Thread.currentThread().getName() + "正在购买第" + tickets-- + "张票");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
SynchonzedTexte01 synchonzedTexte01 = new SynchonzedTexte01();
new Thread(synchonzedTexte01,"zhangsan").start();
new Thread(synchonzedTexte01,"lisi").start();
new Thread(synchonzedTexte01,"wangwu").start();
}
}
同步块:this
//synchronized(this){}
class SynchonzedTexte02 implements Runnable {
int tickets = 100;
@Override
public void run() {
while (true) {
synchronized (this) {
if (tickets <= 0) {
break;
}
System.out.println(Thread.currentThread().getName() + "正在购买第" + tickets-- + "张票");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
SynchonzedTexte02 synchonzedTexte02 = new SynchonzedTexte02();
//创建3个线程
new Thread(synchonzedTexte02,"zhangsan").start();
new Thread(synchonzedTexte02,"lisi").start();
new Thread(synchonzedTexte02,"wangwu").start();
}
}
同步块:资源
synchronized(资源){}
class SynchonzedTexte03 implements Runnable {
Integ integ=new Integ();
@Override
public void run() {
while (true) {
synchronized (integ) {
if (integ.integer <= 0) {
break;
}
System.out.println(Thread.currentThread().getName() + "正在购买第" + integ.integer-- + "张票");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
SynchonzedTexte03 synchonzedTexte03 = new SynchonzedTexte03 ();
//创建3个线程
new Thread(synchonzedTexte03,"zhangsan").start();
new Thread(synchonzedTexte03,"lisi").start();
new Thread(synchonzedTexte03,"wangwu").start();
}
}
class Integ{
Integer integer=50;
}
生产者消费者问题:红绿灯
public class ShengchanZhe {
public static void main(String[] args) {
Seet seet=new Seet();
new Thread(new Car1(seet)).start();
new Thread(new Man1(seet)).start();
}
}
class Car1 implements Runnable{
Seet seet;
public Car1(Seet seet) {
this.seet = seet;
}
@Override
public void run() {
while (true){
seet.caR();
}
}
}
class Man1 implements Runnable{
Seet seet;
public Man1(Seet seet) {
this.seet = seet;
}
@Override
public void run() {
while (true){
seet.maN();
}
}
}
class Seet{
boolean aBoolean=false;
public synchronized void caR() {
if (aBoolean==false){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("车走");
aBoolean=true;
this.notify();
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public synchronized void maN() {
if (aBoolean==true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("人走");
aBoolean=false;
this.notify();
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}