[知了堂学习笔记]线程

1.进程和线程
进程:完整的程序功能
线程:进程的执行单元
进程是对线程的一个封装,一个进程至少应该有一个线程
同时:进程是具有同时性(时间片轮转),线程也具有同时性
本质上就是线程的同时性
进程把线程封装了,进程之间不能资源共享
线程是可以资源共享的
JVM起进程:多线程,执行main/GC(守护线程)

2.多线程—工人模型
每一个工人————-线程(Thread)
工人任务—————-Runnable/Thread run()
工人执行任务———-启动多线程

这里写图片描述

package thread_1;
/**
 * 工人模型
 * 工人--线程
 * 任务
 * 工人开始执行任务--线程启动
 * @author Administrator
 *
 */
public class Thread_1 {

    public static void main(String[] args) {
        Task task = new Task();//任务就是Runnable--run()

        Thread w1 = new Thread(task);//Thread就是一个工人
        w1.setName("doudou");
        Thread w2 = new Thread(task);
        w2.setName("feifei");


        w1.start();//启动任务 --Thread--start()
        w2.start();
    }
}

/*class Worker extends Thread{//工人

}*/

class Task implements Runnable{//任务

    @Override
    public void run() {
        /*while(true) {*/
            System.out.println(Thread.currentThread()+"任务");//当前线程
        /*}*/
    }

}
package thread_1;
/**
 * 1.Tread本身实现Runnable接口,自己可以设定任务run()
 * 2.线程启动:start(),run()叫做方法调用而不是实现多线程
 * 3.中断线程:flag
 * 4.CPU的控制权希望可以控制一下:让出CPU
 * @author Administrator
 *
 */
public class Thread_2 {
    public static void main(String[] args) throws InterruptedException {
        DD dd = new DD();
        FF ff = new FF();
        dd.start();
        Thread.sleep(1000);//当前线程休眠:让出CPU
        ff.start();
        Thread.sleep(1000);
        /*dd.stop();*/
        //dd.interrupt();
        dd.shutUp();//手动中断线程

        ff.shutUp();
        /*dd.run();//真正的方法调用
        ff.run();*/
    }
}


class DD extends Thread{

    private boolean flag =true;
    @Override
    public void run() {
        while(flag) {
            System.out.println("我有车");
        }
    }

    public void shutUp() {
        this.flag = false;
    }
}


class FF extends Thread{
    private boolean flag =true;

    @Override
    public void run() {
        while(flag) {
            System.out.println("我有房");
        }
    }

    public void shutUp() {
        this.flag = false;
    }
}
package thread_1;
/**
 * 启动一个线程计算1-1000的和
 * 结果在main主线程中打印
 * @author Administrator
 *
 */
public class Thread_3 {

    public static void main(String[] args) throws InterruptedException {
        Task1 t1 = new Task1();
        Thread t = new Thread(t1);
        t.start();
        /*Thread.sleep(1000);*/
        //t.join();//等待t终止
        t.yield();//暂停当前线程
        System.out.println(t1.getSum());
    }

}


class Task1 implements Runnable{
    private int sum;

    public int getSum() {
        return sum;
    }

    @Override
    public void run() {
        for(int i = 0;i < 1001;i++) {
            this.sum += i;
        }
    }

}
package thread_1;
/**
 * 抛出InterruputedException异常
 * 线程1 sleep
 * 线程2 打扰线程1
 * @author Administrator
 *
 */
public class Thread_4 {

    public static void main(String[] args) {
        MyThread1 t1 = new MyThread1();
        MyThread2 t2 = new MyThread2(t1);

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


class MyThread1 extends Thread{
    @Override
    public void run() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            System.out.println("被打扰");
            e.printStackTrace();
        }
    }
}


class MyThread2 extends Thread{
    private MyThread1 t1;



    public MyThread2(MyThread1 t1) {
        super();
        this.t1 = t1;
    }



    @Override
    public void run() {
        System.out.println("中断线程");
        t1.interrupt();
    }
}

3.线程的状态(生命周期)

New Thread():线程被创建
线程可运行状态:抢到CPU才是真正的运行状态
运行过程中CPU被抢,阻塞,休眠sleep()/wait()
结束—–线程自动运行完/推荐:标志位

这里写图片描述

4.线程的常用方法
Start():才能开始多线程
Stop():终止线程,但不推荐
Interrupt():打断线程的状态,线程受阻,不能真正中断线程
Sleep():当前线程休眠,让出CPU,不让出锁
Join():等待线程中止
Yield():暂停当前线程
setPriority():设置线程的优先级别
setName():设置线程的名字
isAlive():测试线程是否为活动状态

线程通信
wait()
notify()
notifyAll()

5.线程同步
锁:每个对象都有一个锁,而且每个锁都只有唯一一把钥匙
保护资源,一把锁只有一把钥匙,只有执行完被锁住的程序块钥匙才能释放
同步:使用了同一个锁的代码块就叫实现了同步
同步块
同步方法
锁:
当前对象锁:synchronized(this)/普通同步锁
类锁(Class对象锁):synchronized(类.class)/静态同步方法锁
私有锁:室友类中的一个成员属性作为锁

锁保护谁:成员属性/静态成员属性/
锁有几种:(互斥锁)
this:当前对象的锁
类.class:当前类的Class对象的锁
成员属性
方法上加锁:锁就是this对象的锁
静态方法上加锁:锁就是Class实例对象的锁
锁属于谁:
锁是属于对象的
每一个对象都有唯一的锁

package thread_2;

public class LockTest {
    public static void main(String[] args) {
        final Method m = new Method();
        Thread t1 = new Thread(new Runnable() {

            @Override
            public void run() {
                m.m1();//拿到this锁
            }

        });

        Thread t2 = new Thread(new Runnable() {

            @Override
            public void run() {
                m.m2();//m2需要this锁
            }

        });

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

}

/**
 * m1和m2加锁,加的是this,使用同一把锁
 * @author Administrator
 *
 */
class Method{
    private String lock = "";//lock本身是一个对象,只要是对象就有锁

    public void m1() {
        synchronized (lock) {//加锁
            for(int i = 0 ;i < 5; i++) {
                System.out.println(Thread.currentThread().getName()+" "+i);
            }
        }

    }
    public void m2() {
        synchronized (lock) {

            for(int i = 0 ;i < 5; i++) {
                System.out.println(Thread.currentThread().getName()+" "+i);
            }   

        }

    }

}
package thread_2;

public class TicketTest {
    public static void main(String[] args) {
        SaleTask sal = new SaleTask();
        Thread t1 = new Thread(sal);
        t1.setName("网上");
        Thread t2 = new Thread(sal);
        t1.setName("电话");
        Thread t3 = new Thread(sal);
        t1.setName("现场");

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


}

class SaleTask implements Runnable{

    int id = 100;//t1,t2,t3共同使用id这个变量

    @Override
    public void run() {
        while(true) {
            synchronized (this) {//加锁:钥匙只有一把  拿到钥匙

                if(id>0) {//t1(1),t2(1),t3(1)
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    System.out.println("卖票:"+id--);
                }else {
                    System.out.println("票卖完");
                    break;
                }

            }//拿到钥匙后只有执行到这里钥匙才能归还
        }
    }

}

锁的使用

package thread_2;

public class ReadProject {
    public static void main(String[] args) throws InterruptedException {
        Method1 m = new Method1();//任务类
        Thread t1 = new Thread(m);

        t1.start();
        m.m2("主线程2");
        Thread.sleep(1000);
        m.m1("主线程1");

        //m.m1("主线程1");
        //start()--主线程1 m1----主线程2 m2 --子线程m1

        //t1.start.run m1(m)
        //main  m1(m)
        //main  m2(m)
    }

}
class Method1 implements Runnable{
    public int b = 100;
    public synchronized void m1(String name) throws InterruptedException {
        System.out.println("进入m1");
        Thread.sleep(1000);
        System.out.println("m1:"+b+":"+name);
    }
    public /*synchronized*/ void m2(String name) throws InterruptedException {
        b = 200;
        System.out.println("进入m2");
        Thread.sleep(1000);
        System.out.println("m2:"+b+":"+name);
    }
    @Override
    public void run() {
        System.out.println("进入子线程");
        try {
            m1("子线程");
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

死锁
相互等待对方占用的资源(锁)


这里写图片描述


package thread_2;

public class DeadLockTest {
    public static void main(String[] args) {
        DeadLock t1 = new DeadLock(0);
        DeadLock t2 = new DeadLock(1);

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

}

class DeadLock extends Thread{
    //一定是static才能形成死锁,如果没有static就是两个对象,不会形成死锁
    private static String lock1 = new String();
    private static String lock2 = new String();

    private int flag;

    public DeadLock(int flag) {
        this.flag = flag;
    }

    @Override
    public void run() {
        if(flag == 0) {
            synchronized (lock1) {//t1
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                synchronized (lock2) {

                }

            }
        }else if(flag == 1) {
            synchronized (lock2) {//t2
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                synchronized (lock1) {

                }
            }
        }
    }
}

6.线程通信
线程之间的资源共享
这里写图片描述

生产者-消费者模型

package thread_2;

public class Test {
    public static void main(String[] args) {

        Resouce r = new Resouce();
        Procedure p = new Procedure(r);
        Consummer c = new Consummer(r);


        Thread t1 = new Thread(p);
        Thread t2 = new Thread(p);
        Thread t3 = new Thread(c);
        Thread t4 = new Thread(c);

        t1.start();
        t2.start();
        t3.start();
        t4.start();


    }

}

class Mantou{
    int id;
}
class Resouce{

    Mantou[] arrMantou = new Mantou[6];
    int index = 0;
    public synchronized void push(Mantou mantou) throws InterruptedException {

            if(index == arrMantou.length) {
                //放满了:暂停生产,赶紧消费
                System.out.println("---暂停生产---");
                this.wait();//当前线程任务暂停
                this.notifyAll();//通知赶紧消费

            }else {
                Thread.sleep(100);

                arrMantou[index] = mantou;
                System.out.println("放入:"+(index+1));

                index++;

            }



    }

    public synchronized Mantou pop() throws InterruptedException {

            if(index == 0) {
                //取完了:暂停消费,赶紧生产
                System.out.println("---暂停消费---");
                this.wait();
                this.notifyAll();

            }else {
                System.out.println("取出:"+index);
                Thread.sleep(100);
                index--;

            }
            return arrMantou[index];



    }
}

class Procedure implements Runnable{

    private Resouce resource;

    public Procedure(Resouce resource) {
        this.resource = resource;
    }

    @Override
    public void run() {

        while(true) {
            Mantou mantou = new Mantou();
            try {
                resource.push(mantou);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

}

class Consummer implements Runnable{

    private Resouce resource;


    public Consummer(Resouce resource) {

        this.resource = resource;
    }


    @Override
    public void run() {
        while(true) {
            try {
                Mantou mantou = resource.pop();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

}

7.线程池
线程池中有很多存在的线程
好处:节约时间,管理线程,简化工作量

这里写图片描述

package thread_3;

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

public class ThreadPoolTest {

    public static void main(String[] args) {
        //执行单个线程的线程池
        //ExecutorService pool = Executors.newSingleThreadExecutor();
        //执行固定线程的线程池
        //ExecutorService pool = Executors.newFixedThreadPool(2);
        //可以新建线程的线程池
        /*ExecutorService pool = Executors.newCachedThreadPool();

        MyTask task1 = new MyTask();//runnable,run
        MyTask task2 = new MyTask();
        MyTask task3 = new MyTask();
        MyTask task4 = new MyTask();
        MyTask task5 = new MyTask();

        pool.execute(task1);//任务交给线程池执行
        pool.execute(task2);
        pool.execute(task3);
        pool.execute(task4);
        pool.execute(task5);

        pool.shutdown();*/

        //实现调度的线程池
        ScheduledExecutorService pool = Executors.newScheduledThreadPool(2);

        pool.scheduleAtFixedRate(new Runnable() {

            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"*******");
            }
        }, 1000, 5000, TimeUnit.MICROSECONDS);
        pool.scheduleWithFixedDelay(new Runnable() {

            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"------------");
            }
        }, 1000, 3000, TimeUnit.MICROSECONDS);

    }
}

模拟线程池
1.ThreadPool:线程池 List<Thread>
2.ThreadTask: 执行任务的线程
3.Task:任务 abstract
4.TaskQueue:任务队列


请关注“知了堂学习社区”,地址:http://www.zhiliaotang.com/portal.php

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值