Day10(多线程)


多线程

Thread类

 package cn.ljy.myproject01;
 /**
  * @Author liu
  * @Date 2021/11/25 10:35
  * @Description 测试Thread类证明线程不一定立即执行
  * 创建线程方式一:继承Thread类,重写run()方法,调用start()来开启线程
  * @Since version-1.0
  */
 
 public class TextThread extends Thread{
     //重写线程的run方法
     @Override
     public void run() {
         for (int i = 0; i < 20; i++) {
             System.out.println("我在学习多线程!");
        }
    }
 
     public static void main(String[] args) {
         //main线程,主线程(也就是用户线程)
         //创建一个线程对象
         TextThread t = new TextThread();
         t.start();//调用start()来开启线程
 
 
         for (int i = 0; i < 2000; i++) {
             System.out.println("我在打代码!");
        }
    }
 }
 

 

Runnable接口

 package cn.ljy.myproject01;
 /**
  * @Author liu
  * @Date 2021/11/25 11:21
  * @Description 创建多线程的第二种方式:实现Runnable接口
  * @Since version-1.0
  */
 public class TestRunnable implements Runnable{
 
     @Override
     public void run() {
         for (int i = 0; i < 20; i++) {
             System.out.println("我在学习多线程!"+i);
        }
    }
 
     public static void main(String[] args) {
         TestRunnable t = new TestRunnable();
         t.run();//只是单纯的运行的那个t这个类的程序。并没有做到同时进行
         new Thread(t).start();//同时进行
         for (int i = 0; i < 200; i++) {
             System.out.println("我在打代码!!"+i);
        }
    }
 }
 
  • 与Thread不同的是需要传入目标对象+Thread对象.start(),才可以开启线程。

 

龟兔赛跑

 package cn.ljy.myproject01;
 
 public class Race implements Runnable{
     private static String Winter ;//声明一个胜利者
     @Override
     public void run() {//重写一个run方法跑100步
         for (int i = 1; i <= 100; i++) {
             if (Thread.currentThread().getName().equals("兔子")&&i==50 ){
                 try {
                     Thread.sleep(1);
                } catch (InterruptedException e) {
                     e.printStackTrace();
                }
            }
             System.out.println(Thread.currentThread().getName() + "-->第" + i + "步");
             boolean flag = GameOver(i);//调用GameOver方法来进行比赛的判断
 
             if (flag){
                 break;
            }
        }
    }
     /**
      * @Author liu
      * @Date 2021/11/25 20:14
      * @Description 定义一个比赛结束的判断当有胜利者的时候结束,当跑到第100步的时候结束,其余情况不结束。
      * @Param [step]
      * @Return java.lang.Boolean
      * @Since version-1.0
      */
     private Boolean GameOver(int step) {
         if (Winter != null) {
             return true;
        }{if(step>=100){
             Winter =Thread.currentThread().getName();
             System.out.println("胜利者:"+Winter);
             return true;
        }
 
        }return  false;
    }
     //主线程运行线程
     public static void main(String[] args) {
         Race race = new Race();
         new Thread(race,"兔子").start();
         new Thread(race,"乌龟").start();
 
    }
 
 
 }
 

Callable

 package cn.ljy.myproject01;
 
 import java.util.concurrent.*;
 
 //创建线程的第三种方法
 public class TestCallable implements Callable<String> {
     private static String Winter ;//声明一个胜利者
     @Override
     public String call() {//重写一个run方法跑100步
         for (int i = 1; i <= 100; i++) {
             if (Thread.currentThread().getName().equals("兔子")&&i==50 ){
                 try {
                     Thread.sleep(1);
                } catch (InterruptedException e) {
                     e.printStackTrace();
                }
            }
             System.out.println(Thread.currentThread().getName() + "-->第" + i + "步");
             boolean flag = GameOver(i);//调用GameOver方法来进行比赛的判断
 
             if (flag){
                 break;
            }
        }return null;
    }
     /**
      * @Author liu
      * @Date 2021/11/25 20:14
      * @Description 定义一个比赛结束的判断当有胜利者的时候结束,当跑到第100步的时候结束,其余情况不结束。
      * @Param [step]
      * @Return java.lang.Boolean
      * @Since version-1.0
      */
     private Boolean GameOver(int step) {
         if (Winter != null) {
             return true;
        }{if(step>=100){
             Winter =Thread.currentThread().getName();
             System.out.println("胜利者:"+Winter);
             return true;
        }
 
        }return  false;
    }
 
     public static void main(String[] args) throws ExecutionException, InterruptedException {
         TestCallable t1 = new TestCallable();
         //创建执行服务(创建池:需要多少的线程写多少)
         ExecutorService ser = Executors.newFixedThreadPool(2);
         //提交执行
         Future<String> r = ser.submit(t1);
         Future<String> t = ser.submit(t1);
         //获取结果
         String rabbit =r.get();
         String tortoise =t.get();
 
         //关闭服务
         ser.shutdownNow();
 
    }
 }
 

Lambda

 package cn.ljy.myproject01;
 /**
  * @Author liu
  * @Date 2021/11/27 22:08
  * @Description 推导lambda表达式
  * @Since version-1.0
  */
 public class TestLambda {
     //3.静态内部类(要加static)
     static class Like2 implements ILike{
 
         @Override
         public void lambda() {
             System.out.println("i like lambda2!");
        }
    }
     public static void main(String[] args) {
         //普通类的实例(使用接口声明)
         ILike like = new Like();
         like.lambda();
         //静态内部类的实例
         like = new Like2();
         like.lambda();
         //4.局部内部类
         class Like3 implements ILike{
 
             @Override
             public void lambda() {
                 System.out.println("i like lambda3!");
            }
        }
         //局部内部类的实例
         like = new Like3();
         like.lambda();
         //5.匿名内部类(没有类的名字,接住接口来进行实例化)
         like = new ILike() {
             @Override
             public void lambda() {
                 System.out.println("i like lambda4!");
            }
        };
         like.lambda();
         //6.使用lambda表达式
         like=()->{
             System.out.println("i like lambda5!");
        };
         like.lambda();
    }
 }
 //1.创建一个函数式接口
 interface ILike{
     void lambda();
 }
 //2.实现类(实现这个接口的类)
 class Like implements ILike{
 
     @Override
     public void lambda() {
         System.out.println("i like lambda1!");
    }
 }
  • lambda表达式使用情况:接口为函数式接口的时候才可以使用

  • lambda表达式可以继续进行简化:

    • 1.简化掉参数类型(什么类型都可以去掉):变量类型要都去掉的的时候才可以使用,有一个没去掉就不可以去掉变量类型。

    • 2.简化掉括号():将函数类型都去掉的时候可以去掉括号,为多个参数的时必须要加上括号

    • 3.简化掉花括号{}:必须要方法体为一的情况下才可以去掉花括号

线程方法

setPriority(int newPriority):更改线程优先级

static void sleep(long millis):指定毫秒是让线程休眠

void join():强制插队(先完成插队的线程在进行)

static void yield():(也就是礼让,但礼让不一定会成功看cpu心情)暂停当前正在执行的线程对象,并执行其他线程。

boolean isAlive():查看线程是否存活

currentThread():返回对当前正在执行的线程对象的引用。

proiority:线程的优先级

 

stop()

 package cn.ljy.myproject01;
 
 public class TestStop implements Runnable{
     //1.设置一个标志位
     Boolean flag = true;
     @Override
     public void run() {
         int i = 0;
         while(flag){
             System.out.println("I+" + i++);
        }
    }
     //2.设置一个公共方法停止线程,标志位转换
     public  void stop(){
         this.flag=false;
    }
 
 
     public static void main(String[] args) {
         TestStop testStop = new TestStop();
         new Thread(testStop).start();
         for (int i = 0; i < 1000; i++) {
             System.out.println("mian"+i);
             if(i == 900){
                 testStop.stop();
                 System.out.println("已被停止");
            }
        }
    }
 }
 

Sleep

 package cn.ljy.myproject01;
 
 import java.text.SimpleDateFormat;
 import java.util.Date;
 
 public class TestSleep {
     public static void main(String[] args) throws InterruptedException {
         //打印当前系统时间
         Date startTime = new Date(System.currentTimeMillis());//获取系统当前时间
         while(true){
             Thread.sleep(1000);
             System.out.println(new SimpleDateFormat("HH:mm:ss").format(startTime));
             startTime = new Date(System.currentTimeMillis());//更新当前时间
        }
    }
     public static void tenDown() throws InterruptedException {
 
 
 
         int i=10;
         while(true){
 
             System.out.println(i--);
             Thread.sleep(1000);
             if (i<=0)
                 break;
        }
 
    }
 }
 
  • 每个对象都有一把锁,sleep不会释放锁

Join()

 package cn.ljy.myproject01;
 
 public class TestJoin implements Runnable {
 
     @Override
     public void run() {
         for (int i = 0; i < 100; i++) {
             System.out.println("我是vip");
        }
    }
 
     public static void main(String[] args) throws InterruptedException {
         //启动我们的线程
         TestJoin testJoin = new TestJoin();
         Thread thread = new Thread(testJoin);
 
         //thread.sleep(5000);
 
         for (int i=0;i<500;i++){
             if (i==100){
                 thread.start();
                 thread.join();//插队,让正在运行的线程停下来等待要插队的线程完成后,在继续完成刚刚在运行的线程
            }
 
             System.out.println("Main"+i);
 
        }
    }
 }
 

State

image-20211130105727593

package cn.ljy.myproject01;
/**
* @Author liu
* @Date 2021/11/30 10:43
* @Description 观测线程的状态
* @Since version-1.0
*/
public class TestState {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(()->{
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("/////////");
});

//观察状态
Thread.State state = thread.getState();
System.out.println(state);
//观察启动后
thread.start();//启动线程
state = thread.getState();
System.out.println(state);//Run

while(state !=Thread.State.TERMINATED){
Thread.sleep(100);
state = thread.getState();//更新线程状态
System.out.println(state);//输出状态
}
}
}

优先级

package cn.ljy.myproject01;

import sun.awt.windows.ThemeReader;

public class TestPriority {
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);

//设置优先级启动线程
t1.start();

t2.setPriority(Thread.MAX_PRIORITY);
t2.start();

t3.setPriority(1);
t3.start();

t4.setPriority(4);
t4.start();
}


}
class MyPriority implements Runnable{

@Override
public void run() {
//打印出当前正在运行的线程的名字和优先级
System.out.println(Thread.currentThread().getName()+"->"+Thread.currentThread().getPriority());

}
}

deamon

守护线程等用户线程结束直接结束。

package cn.ljy.myproject01;
//设置守护线程
//上帝守护你
public class TestDaemon {
public static void main(String[] args) {
God god = new God();
Your you = new Your();

Thread thread = new Thread(god);
thread.setDaemon(true);//默认是false表示是用户线程,正常的都是用户线程


thread.start();//上帝线程启动

new Thread(you).start();//用户线程启动

}
}
class God implements Runnable{
@Override
public void run() {
while(true){
System.out.println("上帝会保佑你");
}
}
}
class Your implements Runnable{
@Override
public void run() {
for (int i = 0; i < 36500; i++) {
System.out.println("开心的或者");
}
System.out.println("----============Goodbye! world!
--------============");

}
}

线程的的不安全问题

package cn.ljy.myproject01;
//不安全的买票
//线程不安全会产生负数
public class UnsafeBuyTicket {
public static void main(String[] args) {
BuyTicket ticketEr = new BuyTicket();

new Thread(ticketEr,"me").start();
new Thread(ticketEr,"you").start();
new Thread(ticketEr,"yellow").start();

}
}
class BuyTicket implements Runnable{
private int ticketNum = 10;
boolean flag = true;//线程停止的标志
@Override
public void run() {
//买票
while(flag){
try {
buy();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

}
private void buy() throws InterruptedException {
//判断是否有票
if(ticketNum <= 0){
flag = false;

}
Thread.sleep(1000);//延迟让结果更加明显
System.out.println(Thread.currentThread().getName() + "拿到" + ticketNum--);
}
}

解决不安全问题

package cn.ljy.myproject01;

//不安全的买票
//线程不安全会产生负数
public class TestSynchronized {
public static void main(String[] args) {
BuyTicket1 ticketEr = new BuyTicket1();

new Thread(ticketEr,"me").start();
new Thread(ticketEr,"you").start();
new Thread(ticketEr,"yellow").start();

}
}
class BuyTicket1 implements Runnable{
private int ticketNum = 10;
boolean flag = true;//线程停止的标志
@Override
public void run() {
//买票
while(flag){
try {
buy();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

}
private synchronized void buy() throws InterruptedException {
//判断是否有票
if(ticketNum <= 0){
flag = false;
return;
}
// Thread.sleep(1000);//延迟让结果更加明显
System.out.println(Thread.currentThread().getName() + "拿到" + ticketNum--);
}
}
  • 使用synchronized将方法锁住。

  • 使用synchronized(Obj){}将对象锁住。Obj称为同步监视器

DeadLock(死锁)

package cn.ljy.thread;

import sun.awt.windows.ThemeReader;
//死锁:多个线程互相抱有资源,然后形成僵直
public class DeadLock {
public static void main(String[] args) {
Makeup t1 = new Makeup(0,"小白");
Makeup t2 = new Makeup(1,"小红");

t1.start();
t2.start();
}




}

//口红
class Lipstick{

}

//镜子
class Mirror{
}
class Makeup extends Thread{
//需要一份镜子和口红
static Lipstick lipstick = new Lipstick();
static Mirror mirror = new Mirror();

int choice;//选择
String girlName;

Makeup(int choice ,String girlName){
this.choice = choice;
this.girlName = girlName;
}

@Override
public void run() {
//化妆
try {
makeup();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void makeup() throws InterruptedException {
if(choice==0){
synchronized (lipstick) {
System.out.println(this.girlName+"获得口红");
Thread.sleep(1000);

}synchronized(mirror){
System.out.println(this.girlName+"获得镜子");
}

}
else{
synchronized (mirror){
System.out.println(this.girlName+"获得镜子");
Thread.sleep(2000);

}synchronized (lipstick){
System.out.println(this.girlName+"获得口红");
}

}
}
}

notifyAll(),wait() 管程流

package cn.ljy.thread.gaoji;
//测试生产者和消费者模型,----》利用缓冲区来进行,管程法
//生产者,消费者,产品,缓冲区
public class TestPc {
public static void main(String[] args) {
synContainer container = new synContainer();

new Producer(container).start();
new Consumer(container).start();
}
}
//生产者
class Producer extends Thread{
synContainer container;
public Producer(synContainer container){
this.container=container;
}

@Override
public void run() {
for (int i = 1; i <=20 ; i++) {
try {
container.push(new Chicken(i));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("生产"+i+"鸡");

}
}
}
//消费者
class Consumer extends Thread{
synContainer container;
public Consumer(synContainer container){
this.container=container;
}

@Override
public void run() {
for (int i = 1; i <=20; i++) {
try {
System.out.println("买了"+container.pop().id+"鸡");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
//产品
class Chicken{
int id;//产品编号
public Chicken(int id){
this.id = id;
}
}
//缓冲区
class synContainer{
//需要一个容器大小
Chicken[] chickens = new Chicken[9];
int count = 0;
//生产者放入产品
public synchronized void push(Chicken chicken) throws InterruptedException {
//如果容器满了,就叫消费者来进行消费。
if(count==chickens.length){
//通知消费消费,生产者等待
this.wait();
}
//如果容器没有满的话,将产品放进容器
chickens[count]=chicken;
count++;
//通知购买
this.notifyAll();
}
//消费者取出产品
public synchronized Chicken pop() throws InterruptedException {
//判官是否有产品消费
if(count==0){
//消费者等待
this.wait();
}
//如果可以进行消费
count--;
Chicken chicken=chickens[count];
//叫生产者生产
this.notifyAll();
return chicken;
}
}

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM