• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

关于java:线程学习

java 搞代码 4年前 (2022-01-28) 18次浏览 已收录 0个评论

线程的创立形式
继承Thread
继承Therad类,并重写run()办法

public class T1 extends Thread{

@Override
public void run(){

}

public static void main(String[] str){
    T1 t1=new T1();
    t1.start();
}

}
实现Runnable
实现Runnable,并重写run()办法,调用时应用Therad包裹

public class T1 implements Runnable{

@Override
public void run(){

}

public static void main(String[] str){
    T1 t1=new T1();
    Thread t2=new Thread(t1);
    t2.start();
}

}
lambda 简化
new Thread(

()->{}

).start();
线程的五大状态
image.png

状态 形容
创立状态 new进去的时候就是创立状态
就绪状态 调用是start() 就是就绪状态
运行状态 就绪状态失去cpu的调度,进入运行状态
阻塞状态 线程运行暂停,就是阻塞状态,例如调用sleep(),阻塞状态之后会进入就绪状态
死亡状态 线程执行结束或被终止
线程的操作
线程的进行
JDK提供的Stop(),destroy()都已废除,不倡议用
倡议应用一个标记位进行终止变量,或等线程本人进行

public class T1 implements Runnable{

private Boolean f=true;
@Override
public void run(){
    int a=0;
    while(f){
            System.out.println(a++);
    }
}
public void stop(){
    f=false;
}

public static void main(String[] str){
    T1 t1=new T1();
    Thread t2=new Thread(t1);
    t2.start();

    for (int a=0;a<1000;a++){
        if (a==900){
            t1.stop();
        }
    }
}

}
线程的休眠 sleep()
sleep指定线程阻塞的毫秒数,毫秒即千分之一秒
sleep存在异样
sleep执行实现后进入就绪状态
sleep不会开释锁

new Thread(()->{

                try { 
                    int a=10;
                    while(a>=0){
                        Thread.sleep(1000);
                        System.out.println(a--);
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();

线程礼让 yield()
将执行的线程暂停但不阻塞
将线程从运行状态转为就绪状态
礼让之后调度状态随机

Thread thread1 = new Thread(() -> {

        System.out.println("线程开始");
        Thread.yield();
        System.out.println("线程进行");
    });
    Thread thread = new Thread(() -> {
        System.out.println("线程开始1");
        Thread.yield();
        System.out.println("线程进行1");
    });
    thread1.start();
    thread.start();;

线程插队 join()
Join合并线程,当此线程执行实现后,能力执行其余线程,其余线程阻塞

public static void main(String[] args) {

    Thread thread1 = new Thread(() -> {
        for(int i=0;i<1000;i++) {
            System.out.println("线程VIP");
        }
    });
    for (int i=0;i<1000;i++){
        if (i==900){
            try {
                thread1.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println(i);
    }

}

守护线程
线程分为用户线程和守护线程
虚拟机必须确保用户线程执行结束,不必期待守护线程执行结束
守护线程如记录日志,监控内存,垃圾回收等

并发
同一个对象被多个线程同时操作就是并发

线程同步
为了解决多个并发问题,引入锁机制synchronized ,党当一个对象取得锁,独占资源,其余线程必须期待,应用后开释锁即可
锁带来的问题

一个线程持有锁会导致其余须要此锁的线程挂起
多个线程竞争,加锁开释锁引起性能问题
高优先级线程期待低优先级呈现优先级倒置,引起性能问题
锁就是要锁变动的对象

同步办法
对于简略的不是批改其余对象的办法,能够间接应用synchronized锁定以后办法

写法就是间接在办法中增加synchronized 关键字

@Override

public synchronized void run() {
    while (f){
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"买到"+p--);
        if (p<=0){
            f=false;
        <b style="color:transparent">来源gao@dai!ma.com搞$代^码网</b>    return;
        }
    }
}

同步块
当线程批改了以后办法外的其余对象,就须要应用同步块

格局:

synchronized (加锁对象){
线程办法
}
例如:

@Override

public  void run() {
        while (f){
            synchronized (qian){
            if (qian.getM()<=0){
                f=false;
                break;
            }
            qian.setM(qian.getM()-yici);
            System.out.println("取出"+yici+"还剩"+qian.getM());
        }
    }
}

Lock锁
Lock是显式锁(手动开关),synchronization是隐式锁,出了作用域主动开释
Lock没有办法锁,只有代码块锁
Lock锁性能更好,扩展性更高
优先应用Lock,其次同步块,其次同步办法

罕用Lock锁,ReentrantLock (可重入锁)

private final ReentrantLock a=new ReentrantLock();
@Override
public  void run() {
    while (f){
        try {
            a.lock();
            if (p<=0){
                f=false;
                return;
            }
            Thread.sleep(100);
            System.out.println(Thread.currentThread().getName()+"买到"+p--);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            a.unlock();
        }
    }
}

死锁
死锁即两个或多个线程,都在期待对方开释锁,如多个同步块嵌套

产生死锁的四个必要条件
互斥条件
一个资源每次只能被一个过程应用
申请与放弃条件
线程阻塞时对已持有锁不开释
不剥夺条件
过程以取得的资源,在未应用完之前,不能强行剥夺
循环期待条件
多个过程之间闭环期待开释
线程通信
生产生产模式
管程法
即线程独特操作一个容器,生产者生产的产品放到容器的产品汇合,消费者从产品汇合中取出产品

生产者:
产品汇合满了,线程期待,期待消费者生产后唤醒生产者
没满就存入,而后唤醒消费者

消费者:
没产品了就期待,生产者生产了产品后会唤醒消费者
有产品就生产,而后唤醒生产者

public class Test6 {

public static void main(String[] args) {
    容器 r=new 容器();
    生产者 s=new 生产者(r);
    消费者 x=new 消费者(r);
    Thread ts=new Thread(s);
    Thread tx=new Thread(x);
    ts.start();
    tx.start();
}

}

class 生产者 implements Runnable{

容器 r;

public 生产者(容器 r) {
    this.r = r;
}

@Override
public  void run() {
    for (int a=0;a<100;a++){
        r.放入(new 产品(a));
        System.out.println("生产了"+a);
    }
}

}
class 消费者 implements Runnable{

容器 r;

public 消费者(容器 r) {
    this.r = r;
}

@Override
public  void run() {
    for (int a=0;a<100;a++){
        System.out.println("------------取出了"+r.取出().id);
    }
}

}
class 产品{

int id;

public 产品(int id) {
    this.id = id;
}

}
class 容器{

产品[] 产品容器=new 产品[20];
int 数量=0;
public synchronized void 放入(产品 c){
        try {
            if (数量==产品容器.length) {
                this.wait();
            }
            产品容器[数量]=c;
            数量++;
            this.notifyAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

public synchronized 产品 取出() {
    try {
        if (数量==0){
            this.wait();
        }
    }catch (Exception e){

    }
   数量 --;
    产品 c=产品容器[数量];
    this.notifyAll();
    return c;
}

}
信号灯法
信号灯法就是在交互层,搁置一个标记位,如果为真,生产者操作,如果为假,消费者操作,操作完都会取反。

public class Test7 {

public static void main(String[] args) {
    交互 j=new 交互();
    生产 s=new 生产(j);
    生产 x=new 生产(j);
    Thread ts=new Thread(s);
    Thread tx=new Thread(x);
    ts.start();
    tx.start();
}

}
class 生产 implements Runnable{

交互 j;

public 生产(交互 j) {
    this.j = j;
}

@Override
public void run() {
    for (int a=0;a<100;a++){
        j.生产("节目---"+a);
    }
}

}
class 生产 implements Runnable{

交互 j;

public 生产(交互 j) {
    this.j = j;
}

@Override
public void run() {
    for (int a=0;a<100;a++){
        j.生产();
    }
}

}
class 交互{

String a="";
boolean f=true;


public synchronized void 生产(String s){
    if (!f){
        try {
            this.wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    System.out.println("生产了"+s);
    this.a=s;
    this.notifyAll();
    f=!f;
}

public synchronized void 生产(){
    if (f){
        try {
            this.wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    System.out.println("生产了"+a);
    this.notifyAll();
    f=!f;
}

}
线程池


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:关于java:线程学习

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址