java--浅谈多线程

多线程:

1、多线程的概述

进程和线程:
在这里插入图片描述
进程想要执行任务就需要依赖线程,一个进程运行时产生了多个线程

2、线程生命周期

在这里插入图片描述

3、创建线程的方法(三种)

创建方式1:
子类Thread。在Thread类自身实现Runnable,但其run方法不起作用。应用程序可以子类Thread提供自己的实现run。

//创建线程方式1:直接继承Thread类
public class TestThread extends Thread{
    @Override
    public void run() {
      //  Thread.currentThread().setName("我是子线程");
        for (int i = 0; i <1000; i++) {
            System.out.println("我是子线程"+i);
        }
    }

    public static void main(String[] args) {
        TestThread tt = new TestThread();
        tt.start();

        for (int i = 0; i < 200; i++) {
            System.out.println("哈哈哈我是主线程"+i);
        }


创建方式二:
提供一个Runnable对象。该 Runnable接口定义了一个方法,run用于包含在线程中执行的代码。该Runnable对象将传递给Thread构造函数。

public class ThreadRunnnable implements Runnable {
    @Override
    public void run() {
        for (int i = 0; i < 50; i++) {
            System.out.println("lalala我是子线程"+i);
        }

    }

    public static void main(String[] args) {
        ThreadRunnnable tr = new ThreadRunnnable();
        Thread thread = new Thread(tr);
        thread.start();
        for (int i = 0; i < 500; i++) {
            System.out.println("主线程"+i);
        }
    }
}

创建方式三:
实现Callable接口,可以有返回值

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;

public class HelloCallable implements Callable {
    int i = 0;
    @Override
    public Object call() throws Exception {
        for (int i1 = 0; i1 < 10; i1++) {
            System.out.println(Thread.currentThread().getName() + ":" + i++);
        }
        return i;
    }
     public static void main(String[] args) {
        HelloCallable helloCallable = new HelloCallable();
        for (int i = 0; i < 10; i++) {
            FutureTask futureTask = new FutureTask(helloCallable);
            Thread thread = new Thread(futureTask, "子线程" + i);
            thread.start();
            try {
                System.out.println("子线程" + i + "返回值:" + futureTask.get());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
    }
}

线程命名:

 //线程的命名
        //1.实例化一个线程对象
        Thread t = new Thread();
        t.setName("custom");
        //输出看看是否有没有实现命名
        System.out.println(t.getName());
        //2.实例化一个对象的同时,通过构造方法对线程命名。这个用于实现Runnable接口的类方便
        Thread t1=new Thread(()->{},"hahha");
        System.out.println(t1.getName());
        //3.类继承Thread,实例化线程对象的同时进行名称的赋值,利用的构造方法
        MyThread m = new MyThread("xixi");
        System.out.println(m.getName());

    }
}
class MyThread extends Thread{
    public MyThread(){}
    public MyThread(String name){
        //super(name);
        this.setName(name);
    }
}

4、线程的状态管理

线程优先级
“高优先级线程”被分配CPU的概率高于“低优先级线程”。只能说提高了概率

public class ThreadPriority implements Runnable {
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println("线程名称:"
                    + Thread.currentThread().getName()
                    + ",线程优先级:"
                    + Thread.currentThread().getPriority()
                    + ",循环:" + i);
        }
    }
    public static void main(String[] args) {
        ThreadPriority threadPriority = new ThreadPriority();
        Thread thread1 = new Thread(threadPriority);
        thread1.setName("线程1");
        thread1.setPriority(Thread.MIN_PRIORITY);
        Thread thread2 = new Thread(threadPriority);
        thread2.setName("线程2");
        thread2.setPriority(Thread.MAX_PRIORITY);
        thread1.start();
        thread2.start();
    }
}

线程休眠:sleep方法
Thread.sleep使当前线程在指定时间段内暂停执行

public class ThreadSleep implements Runnable {
    @Override
    public void run() {
        String info[] = {
                "春眠不觉晓",
                "处处闻啼鸟",
                "夜来风雨声",
                "花落知多少"
        };
        for (int i = 0; i < info.length; i++) {
            System.out.println(info[i]);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
     public static void main(String[] args) {
        ThreadSleep threadSleep = new ThreadSleep();
        Thread thread = new Thread(threadSleep);
        thread.start();
    }
}

线程礼让:yield方法
Thread类中提供了一种礼让方法,使用yield()方法表示,它只是给当前正处于运行状态下的线程一个提醒,告知它可以将资源礼让给其他线程,但这仅仅是一种暗示,没有任何一种机制保证当前线程会将资源礼让。

public class ThreadYield implements Runnable {

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + "开始了");
        Thread.yield();
        System.out.println(Thread.currentThread().getName() + "结束了");
    }

    public static void main(String[] args) {
        ThreadYield threadYield = new ThreadYield();
        Thread thread1 = new Thread(threadYield, "线程1");
        Thread thread2 = new Thread(threadYield, "线程2");
        thread1.start();
        thread2.start();
    }
}

线程联合:join方法
join方法允许一个线程等待另一线程的完成。

public class ThreadJoin implements Runnable {
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("子线程" + i);
        }
    }
    public static void main(String[] args) {
        ThreadJoin threadJoin = new ThreadJoin();
        Thread thread = new Thread(threadJoin);
        thread.start();
        for (int i = 0; i < 100; i++) {
            System.out.println("主线程main" + i);
            if(i == 90) {
                try {
                    thread.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

线程停止
使用标识符进行退出

public class ThreadStop implements Runnable {

    private boolean flag = true;

    @Override
    public void run() {
        int i = 0;
        while (flag) {
            System.out.println("子线程" + i++);
        }

    }

    public void stop() {
        this.flag = false;
    }
     public static void main(String[] args) {
        ThreadStop threadStop = new ThreadStop();
        Thread thread = new Thread(threadStop);
        thread.start();
        for (int i = 0; i < 100; i++) {
            System.out.println("主线程main" + i);
            if (i == 90) {
                threadStop.stop();
                System.out.println("子线程停止了");
            }
        }
    }
}

守护线程:

public class ThreadDaemon {
    public static void main(String[] args) {
        Daemon daemon = new Daemon();
        Thread thread1 = new Thread(daemon);
        thread1.setDaemon(true);
        thread1.start();
        Me me = new Me();
        Thread thread2 = new Thread(me);
        thread2.start();
    }
}
public class ThreadDaemon {
    public static void main(String[] args) {
        Daemon daemon = new Daemon();
        Thread thread1 = new Thread(daemon);
        thread1.setDaemon(true);
        thread1.start();
        Me me = new Me();
        Thread thread2 = new Thread(me);
        thread2.start();
    }
}

5、线程同步和锁

Java编程语言提供了两种基本的同步习惯用法:同步语句(synchronized statements )和同步方法(synchronized methods )
同步语句:

public class SynchronizedStatements implements Runnable {
    public static int ticket = 100;
    @Override
    public void run() {
        while (ticket > 0) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized ("") {
                if (ticket <= 0) {
                    return;
                }
                System.out.println(Thread.currentThread().getName() 
		+ "卖了1张票,剩余" + --ticket + "张票");
            }
        }
    }
    public static void main(String[] args) {
        SynchronizedStatements synchronizedStatements 
		= new SynchronizedStatements();
        Thread thread1 = new Thread(synchronizedStatements, "售票员1");
        thread1.start();
        Thread thread2 = new Thread(synchronizedStatements, "售票员2");
        thread2.start();
        Thread thread3 = new Thread(synchronizedStatements, "售票员3");
        thread3.start();
    }
}

同步方法:
要使同步方法,只需将synchronized关键字添加到其声明中。

public class SynchronizedMethods implements Runnable {
    public static int ticket = 100;

    @Override
    public void run() {
        sellTicket();
    }

    public synchronized void sellTicket() {
        while (ticket > 0) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() 
	+ "卖了1张票,剩余" + --ticket + "张票");
        }
    }
    public static void main(String[] args) {
        SynchronizedMethods synchronizedMethods 
		= new SynchronizedMethods();
        Thread thread1 = new Thread(synchronizedMethods, "售票员1");
        thread1.start();
        Thread thread2 = new Thread(synchronizedMethods, "售票员2");
        thread2.start();
        Thread thread3 = new Thread(synchronizedMethods, "售票员3");
        thread3.start();
    }
}

6、线程协作

多线程环境下,我们经常需要多个线程的并发和协作。这个时候,就需要了解一个重要的多线程并发协作模型“生产者/消费者模式”。

package lianxi;

import java.util.LinkedList;

//测试类:生产者消费者模式
public class Test {
    public static void main(String[] args) {
        LinkedList<Product> list = new LinkedList<>();
        Pool pool = new Pool(list, 6);
        Producer producer = new Producer(pool);
        producer.start();
        Consumer consumer = new Consumer(pool);
        consumer.start();
    }
}

//产品类
class Product {
    //产品名字
    private String name;

    //构造方法对属性进行初始化
    public Product(String name) {
        this.name = name;

    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

//缓冲区
class Pool {
    //装产品的容器
    LinkedList<Product> list;
    int Maxsize;//容量大小

    public Pool(LinkedList<Product> list, int Maxsize) {
        this.list = list;
        this.Maxsize = Maxsize;
    }

    //生产者放产品(同步方法)
    public synchronized void push(Product product) {

        //先判断容器是否满了,没满就等待消费者消费
        if (list.size() == Maxsize) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        //没满就通知生产继续放
        list.add(product);
        // System.out.println("生产者放了一件产品,产品名字为"+product.getName());
        this.notify();
    }


    //消费者拿产品
    public synchronized Product pop() {

        //先判断产品池是否空了,空了就等待生产者生产
        if (list.size() == 0) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        Product pro = list.remove(0);
        //没空 就通知消费者消费
        this.notify();

        //   System.out.println("消费者拿了一件产品,产品名字为"+pro.getName());

        return pro;

    }
}

//生产者生产
class Producer extends Thread {
    Pool pool;

    public Producer(Pool pool) {
        this.pool = pool;
    }

    @Override
    public void run() {
       // int i=0;可以和while(true),i++ 一起使用
        for (int i1 = 1; i1 < 10; i1++) {
            Product p = new Product("牙膏"+i1);
            this.pool.push(p);
            System.out.println("生产了一件" + p.getName());

        }

        }

    }


//消费者消费
class Consumer extends Thread {
    Pool pool;

    public Consumer(Pool pool) {
        this.pool = pool;
    }

    @Override
    public void run() {
       // int i=0;
        for (int i1 = 1; i1 < 10; i1++) {
            Product pop = this.pool.pop();
            System.out.println("消费了一件" + pop.getName());
        }
    }
}


7、线程池

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

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

    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        executorService.execute(new ThreadPool());
        executorService.execute(new ThreadPool());
        executorService.execute(new ThreadPool());
        executorService.shutdown();
    }
}

由于笔者知识范围有限,还有很多不足,欢迎大家提出宝贵的意见和进行补充,后期有新的领悟,也会继续补充!

发布了46 篇原创文章 · 获赞 1 · 访问量 1008

猜你喜欢

转载自blog.csdn.net/qq_42022411/article/details/103276494