java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > java多线程基础

详解Java多线程基础

作者:爱滑雪的码农

这篇文章给大家介绍了Java多线程基础知识,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧

线程创建两种方式

方式 1:继承 Thread 类

继承后重写run(),调用start()启动线程

// 1.定义线程类
class MyThread extends Thread{
    @Override
    public void run() {
        // 线程执行任务
        for (int i = 0; i < 5; i++) {
            System.out.println("线程执行:"+i);
        }
    }
}
// 测试
public class ThreadDemo {
    public static void main(String[] args) {
        MyThread t1 = new MyThread();
        t1.start(); // 启动线程,自动执行run方法
    }
}

方式 2:实现 Runnable 接口

避免单继承限制,更常用

// 1.实现接口
class MyRunnable implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println("任务运行:"+i);
        }
    }
}
public class RunnableDemo {
    public static void main(String[] args) {
        MyRunnable task = new MyRunnable();
        Thread t2 = new Thread(task);
        t2.start();
    }
}

如何实现多线程

// 1.定义线程类
class MyThread extends Thread{
    @Override
    public void run() {
        // 线程执行任务
        for (int i = 0; i < 5; i++) {
            // 加上当前线程名字,你能看清谁在跑
            System.out.println(getName() + " 执行:"+i);
        }
    }
}
// 测试
public class ThreadDemo {
    public static void main(String[] args) {
        // 创建 2 个线程
        MyThread t1 = new MyThread();
        MyThread t2 = new MyThread();
        // 给线程起名字
        t1.setName("线程A");
        t2.setName("线程B");
        // 启动 → 这才是多线程!
        t1.start();
        t2.start();
    }
}
// 1. 定义任务(不是线程,是任务)
class MyRunnable implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            // 打印当前线程名字,能看清谁在跑
            System.out.println(Thread.currentThread().getName() + ":" + i);
        }
    }
}
public class RunnableDemo {
    public static void main(String[] args) {
        // 1. 创建任务
        MyRunnable task = new MyRunnable();
        // 2. 创建 2 个线程,执行同一个任务!!!
        Thread t1 = new Thread(task, "线程1");
        Thread t2 = new Thread(task, "线程2");
        // 3. 启动两个线程 → 这就是多线程!
        t1.start();
        t2.start();
    }
}

线程生命周期

新建new线程对象-调用start(),等待CPU调度-CPU执行run方法-sleep,等待锁,IO阻塞-任务执行完毕/异常终止

sleep 线程休眠

让线程暂停指定毫秒,让出 CPU 执行权

class SleepThread implements Runnable{
    @Override
    public void run() {
        for (int i = 1; i <= 3; i++) {
            System.out.println("计数:"+i);
            try {
                // 休眠1000毫秒=1秒
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
public class SleepTest {
    public static void main(String[] args) {
        new Thread(new SleepThread()).start();
    }
}

线程安全问题 & synchronized 同步锁

多线程同时操作共享数据,会出现数据错乱,加锁保证同一时间仅一个线程访问

//无锁不安全示例
class Ticket implements Runnable{
    private int ticket = 10;
    @Override
    public void run() {
        while (ticket > 0){
            System.out.println("剩余票数:"+ticket--);
        }
    }
}
// 多线程抢票,会出现重复票数、负数票
public class UnSafeTest {
    public static void main(String[] args) {
        Ticket ticket = new Ticket();
        new Thread(ticket,"窗口1").start();
        new Thread(ticket,"窗口2").start();
    }
}
//synchronized 加锁解决安全问题
class SafeTicket implements Runnable{
    private int ticket = 10;
    // 锁对象
    private final Object lock = new Object();
    @Override
    public void run() {
        while (true){
            // 同步代码块,同一时间只允许一个线程进入
            synchronized (lock){
                if(ticket <= 0){
                    break;
                }
                System.out.println(Thread.currentThread().getName()+"出票,剩余:"+ticket--);
            }
        }
    }
}
public class SafeLockTest {
    public static void main(String[] args) {
        SafeTicket ticket = new SafeTicket();
        new Thread(ticket,"窗口A").start();
        new Thread(ticket,"窗口B").start();
    }
}

HashMap vs 线程安全集合

HashMap 为什么线程不安全?

原因:

多线程使用 HashMap 会出现什么问题?

Java 提供哪些线程安全的 Map?

1)HashMap(线程不安全)

单线程用,多线程绝对不能用!

Map<String, String> map = new HashMap<>();

2)Hashtable(线程安全,但性能差)

Map<String, String> map = new Hashtable<>();

3)Collections.synchronizedMap(安全,性能一般)

把不安全的 Map 包装成安全的

Map<String, String> map = Collections.synchronizedMap(new HashMap<>());

4)ConcurrentHashMap(企业级首选!

Map<String, String> map = new ConcurrentHashMap<>();

到此这篇关于Java多线程基础的文章就介绍到这了,更多相关java多线程基础内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文