首页 > 编程语言 > 详细

Java学习5.1阶段总结

时间:2020-05-04 23:34:14      阅读:92      评论:0      收藏:0      [点我收藏+]

今天学完了Java线程的基本知识点,现在总结一下线程里的内容

创建

线程的创建有三个方法,其中两个要掌握使用方法,另一个作为了解

  1. //继承Thread类
    class MyThread1 extends Thread
    //执行
    new MyThread1().start();
    
  2. //实现Runnable接口
    class MyThread2 implements Runnable
    //执行
    new Thread(new MyThread2()).start();
    
  3. class MyThread3 implements Callable<Integer>//了解
    

守护线程

God god = new God();
Thread thread = new Thread(god);
thread.setDaemon(true);

守护线程优先级低,是用来对其他对象和线程提供服务;当JVM的所有线程都是守护线程的时候,守护线程会自动离开,JVM关闭(垃圾回收线程就是守护线程)。

插队

thread.join();

作用:此方法顾名思义,不讲道理的插队

优先级

thread2.setPriority(1);

线程的优先级分为1~10,还有3个常量MIN_PRIORITY = 1,NORM_PRIORITY = 5,MAX_PRIORITY = 10;优先级的值并不能100%决定线程的执行顺序,但相对来说还是数值越高先执行的可能性大

休眠

Thread.sleep(1000);

sleep是以毫秒为单位,1000毫秒 = 1秒

状态

public enum State {
NEW,RUNNABLE,BLOCKED,WAITING,TIMED_WAITING,

详情见Java学习4.24

停止

package Thread;
//建议线程正常停止
//建议使用标志位
//不要使用stop或destroy等不建议使用方法
public class TestStop implements Runnable{

    private boolean flag = true;
    
    @Override
    public void run() {
        int i = 1;
        
        while (flag){
            System.out.println("run Thread" + i++);
        }
    }
    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("main"+i);
            if(i == 900){
                testStop.stop();
                System.out.println("stop");
            }
        }
    }
}


礼让

Thread.yield();

当前线程退出,和其他线程再一同争取

同步(重点、难点)

仍有不理解知识点!

synchronized(Obj){}
//或
public synchroinzed type method()

并发:多个线程同时操作一个资源

处理多线程问题时,多个需要同时访问的线程进入等待池队列

方法:将线程运行的过程(run()方法里面的内容)放入到synchronized(Obj){

}中

锁的对象应该是变化的量(增删改)

同步监视器执行过程:

  1. 第一个线程访问,锁定同步监视器,执行其中代码
  2. 第二个线程访问,发现同步监视器被锁定,无法访问
  3. 第一个线程访问完毕,解锁同步监视器
  4. 第二个线程访问,发现同步监视器没有锁,然后锁定并访问

加锁可以使当前线程锁定,并只让自己执行。(想想一个人进了屋子并反锁,其他人就不等这个解锁就进不去)

	//定义lock锁
    private final ReentrantLock lock = new ReentrantLock();
    lock.lock();//加锁
    lock.unlock();//解锁

线程交互的三种方法

  1. 管控法:利用缓冲区解决。

    思路:在解决生产者——消费者问题时,设立一块缓冲区,并往里面放入产品,如果缓冲区满了就通知生产者先暂停生产,如果缓冲区空了就通知消费者先停止消费。而在非空非满时,生产者或消费者都可以进行生产或消费活动。

    package gaoji;
    //测试:生产者消费者模型 -- > 利用缓冲区解决:管控法
    //生产者,消费者,产品,缓冲区
    public class TesyPC {
        public static void main(String[] args) {
            SynContainer container = new SynContainer();
    
            new Productor(container).start();
            new Consumer(container).start();
        }
    }
    //ctrl + -/+ 快速折叠/展开当前方法
    //ctrl + shift + -/+ 快速折叠/展开所有方法
    //shift + enter快速新建一行
    //生产者
    class Productor extends Thread{
        SynContainer container;
    
        public Productor(SynContainer container) {
            this.container = container;
        }
        //生产
    
        @Override
        public void run() {
            for (int i = 0; i < 100; i++) {
                container.push(new Chicken(i));
                System.out.println("生产了"+i+"只鸡");
            }
        }
    }
    //消费者
    class Consumer extends Thread{
        SynContainer container;
    
        public Consumer(SynContainer container) {
            this.container = container;
        }
    
        @Override
        public void run() {
            for (int i = 0; i < 100; i++) {
                System.out.println("消费了第-->"+container.pop().id+"只鸡");
            }
        }
    }
    //产品
    class Chicken{
        int id;
    
        public Chicken(int id) {
            this.id = id;
        }
    }
    //缓冲区
    class SynContainer{
    //    需要一个容器大小
        Chicken[] chickens = new Chicken[10];
    //    容量计数器
        int count = 0;
        public synchronized void push(Chicken chicken){
            //容器满了等待消费者消费
            //消费者消费消费,生产等待
            if(count == chickens.length) try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    //            容器没满,丢入产品
            chickens[count] = chicken;
            count ++;
    //        可以通知消费者消费了
            this.notifyAll();
        }
        public synchronized Chicken pop(){
            if(count == 0){
                //等待生产者生产,消费者等待
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            //如果可以消费
            count --;
            Chicken chicken = chickens[count];
            //吃完了,通知生产者生产
            this.notifyAll();
            return chicken;
        }
    }
    
    
    
  2. 信号灯法:标志位解决

    设立一个flag标志位(boolean),当为默认值时使一个线程进行,当为默认值的反值时使另一个线程进行(this.flag = !this.flag)

package gaoji;

//信号灯法:标志位解决
public class TestPc2 {
    public static void main(String[] args) {
        TV tv = new TV();
        new Player(tv).start();
        new Wacher(tv).start();
    }
}

//生产则:演员
class Player extends Thread{
    TV tv;

    public Player(TV tv) {
        this.tv = tv;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            if(i%2==0){
                this.tv.play("快乐大本营");
            }else{
                this.tv.play("记录美好生活");
            }
        }
    }
}
//消费者:观众
class Wacher extends Thread{
    TV tv;

    public Wacher(TV tv) {
        this.tv = tv;
    }

    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            this.tv.watch();
        }
    }
}
//产品:节目
class TV{
    //演员表演,观众等待 T
    //观众观看,演员等待 F
    String voice;//表演的节目
    boolean flag = true;
    //表演
    public synchronized void play(String voice){
        if(!flag) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("演员表演了"+voice);
        this.notifyAll();
        this.voice = voice;
        this.flag = !this.flag;
    }
    //观看
    public synchronized void watch(){
        if (flag) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("观看了"+voice);
        this.notifyAll();
        this.flag = !this.flag;
    }
}

  1. 线程池法:
package gaoji;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TestPool {
    public static void main(String[] args) {
         //创建服务,创建线程池
        //参数为线程池大小
        ExecutorService service = Executors.newFixedThreadPool(10);

        //执行
        service.execute(new MyThread());
        service.execute(new MyThread());
        service.execute(new MyThread());
        service.execute(new MyThread());

        //关闭连接
        service.shutdown();
    }
}

class MyThread implements Runnable{

    @Override
    public void run() {
            System.out.println(Thread.currentThread().getName());
    }
}

Java8 新增Lamdba表达式:

不再赘述,举一个例子即可理解:

public class TestLamada2{

    public static void main(String[] args) {
        //原始方法
        ILove love1 = new Ilove(){
            @Override
            public void love(int a){
                System.out.println("I love you" + a) } 
}
        //lambda表达式
        //1.完整格式
        ILove love = (int a) -> {System.out.println("I love you" + a)};
        //2.省略格式
        //如果love方法改为两个以上参数,则()不能省略
        //如果写两行以上方法,则{}不能省略
        //参数类型即使不一样也可以省略
        ILove love = b -> System.out.println("I love you" + b);
        love.love(2);
    }
    }
interface ILove{
    void love(int a);
}

Java学习5.1阶段总结

原文:https://www.cnblogs.com/panmao/p/12828510.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!