java——多线程(快速掌握)

本篇对java中的多线程进行总结,对线程的执行方式:串行、并发进行讲解,以及线程池、同步异步还有一些常用的操作进行了总结,最后通过不同客户购买车票进行了多线程的练习;整体上比较精简,代码可以直接粘贴到idea中执行,方便理解和掌握;

第一篇:线程的基础语法

package java_duoxiancheng;
//TODO 线程:java程序在运行过程中会默认产生一个进程;这个进程会有一个主线程;代码都在这个主线程中进行;
//TODO 线程执行方式:串行、并发;
//串行:多个线程连接成串,然后按照顺序执行
//并发:多个线程独立,谁抢到了CPU的执行权,谁就能执行;
public class java_47 {
    public static void main(String[] args) throws InterruptedException {
        //Thread是线程类;
        //currentThread()方法是获取当前正在运行的线程
        //main方法运行在main线程中
        //首先对于main线程来说,是一直执行的,相对于其他新建的线程是先执行的;
        System.out.println(Thread.currentThread().getName());
        MyThread1 t1=new MyThread1();
        MyThread2 t2=new MyThread2();
        t1.start();
        t2.start();
        //将线程连接成串:如果没将线程连接成串,先输出主线程执行完毕,因为主线程是先执行的,对于t1和t2来说,谁先拿到cpu执行权不一定,现在连接成串后,t1在t2的前面,
        t1.join();
        t2.join();
        System.out.println("主线程执行完毕!");
    }
}
class MyThread1 extends Thread{
    //重写运行指令:
    @Override
    public void run() {//线程执行的内容,这个方法执行结束后,线程就终止了;
        System.out.println("MyThread1"+ Thread.currentThread().getName());
    }
}
class MyThread2 extends Thread{
    public void run(){
        System.out.println("MyThread2"+Thread.currentThread().getName());
    }
}

第二篇:创建线程的方式

package java_duoxiancheng;
//TODO 之前的新建一个线程就要新建一个class类,但是不想这样,因此采用通用的方法来创建线程并执行:
public class java_49 {
    public static void main(String[] args) {
        //以下方式不需要一个类一个类的去创建:
        Thread t1=new Thread(()->{
            System.out.println("线程1执行");
        });
        t1.start();
        Thread t2=new Thread(()->{
            System.out.println("线程2执行");
        });
        t2.start();
        //还有一种方式:传递实现了Runnable接口的类的对象,一般使用匿名类;
        Thread t3=new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("线程执行!");
            }
        });
        t3.start();

    }
}

第三篇:线程池

package java_duoxiancheng;

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

//TODO 线程池:所谓的线程池也就是线程对象的容器;可以根据需要,在启动时,创建一个或者多个线程对象;
// java中有四种常见的线程池;
public class java_50 {
    public static void main(String[] args) {
        //1.创建固定数量的线程对象; ExecutorService是线程服务对象;
//        ExecutorService executorService = Executors.newFixedThreadPool(3);
//        //上方创建了三个线程对象,总共三个线程;但是如果有四个事务需要做的时候,那么第四个事务就会出现阻塞状态,需要等到其中一个线程处理完,然后再处理第四个事务,如下:可以看到有的线程重复执行;
//        for(int i=0;i<5;i++){
//            executorService.submit(new Runnable() {
//                @Override
//                public void run() {
//                    System.out.println(Thread.currentThread().getName());
//                }
//            });
//        }

        //2.根据需求动态创建线程对象:
        //此处创建了五个线程,因为for循环中有五次;但是如果有for循环20次的话,会发现并没有创建20个线程,有重复使用的,所以在线程执行结束后,会再进行处理继续执行;
//        ExecutorService executorService = Executors.newCachedThreadPool();
//        for(int i=0;i<20;i++){
//            executorService.submit(new Runnable() {
//                @Override
//                public void run() {
//                    System.out.println(Thread.currentThread().getName());
//                }
//            });
//        }
        //3.单一线程:如果一些工作是顺序执行的,此时可以用单一线程;
//        ExecutorService executorService = Executors.newSingleThreadExecutor();
//        for(int i=0;i<20;i++){
//            executorService.submit(new Runnable() {
//                @Override
//                public void run() {
//                    System.out.println(Thread.currentThread().getName());
//                }
//            });
//        }
        //4.

    }
}

第四篇:同步异步

package java_duoxiancheng;
//TODO 同步:对于异步来说,就是各个线程互不关联,各自执行各自的;对于同步来说,线程之间就有了关联,
// 一个执行完之后另一个才能执行,之前演示了用join方法来实现,其实有更常用的方法:synchronized关键字

public class java_51 {
    public static void main(String[] args) {
        //TODO synchronized同步关键字:当多个线程来访问同步方法时,只能有一个线程访问;还可以修饰代码块,称之为同步代码块;
            per per = new per();
            Thread t1 = new Thread(per);
            Thread t2 = new Thread(per);
            Thread t3 = new Thread(per);
            t1.start();
            t2.start();
            t3.start();
        }
    }
class per implements Runnable {
        int ticket = 10;
        final String a = "";//任意定义的锁对象,只要保证唯一不变即可
        @Override
        public void run() {
            while (ticket>0) {
                synchronized (a) {//同步代码块,a是锁对象
                    if (ticket > 0) {
                        try {
                            Thread.sleep(1000);//sleep让程序休眠,加大出现问题的概率,方便定位问题,使用时会有异常try..catch即可
                        } catch (Exception e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        System.out.println(Thread.currentThread().getName() + "正在卖第" + ticket + "张票");
                        ticket--;
                    }
                }
            }
        }
    }

第五篇:线程安全问题

package java_duoxiancheng;
//TODO 线程安全问题:
public class java_52 {
    public static void main(String[] args) {
        User user=new User();
        Thread t1=new Thread(()->{
            user.name="zhangsan";
            try {
//注意由于这一秒钟的休眠,所以其他线程可能会执行,因此t2中将相同的对象的name属性改为lisi,
// 这个时候休眠结束后,都打印总会都显示lisi,因为在休眠过程中t2已经将name属性更改了,所以竞争同一个对象这样就会出现线程安全问题;如果没有这个休眠的话,就会出现zhangsan lisi
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(user.name);
        });
        Thread t2=new Thread(()->{
            user.name="lisi";
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(user.name);
        });
        t1.start();
        t2.start();
        System.out.println("主线程执行完毕!");
    }
}
class User{
    String name;
}
  • 22
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小菜日记^_^

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值