java 多线程技术基础

    xiaoxiao2021-03-25  63

    0 概述

    线程是进程中一个独立控制单元,其控制着进程执行。一个进程中至少包含一个线程。 对于java程序来说都是jvm上运行的,运行java程序时候jvm就会启动一个进程,该进程中至少有一线程负责java程序执行,该线程运行的代码存在于main方法中,因此也称当前线程为主线程。下图给出了线程的几种状态。

    1 线程创建

    1.1第一种方式继承Thread类,要覆写其run方法。 覆写run方法的原因: Thread类用于描述线程,该类定义就定义了一个功能,用于存储要运行的代码,也就是Thread类run方法,用于存储线程运行的代码。覆写run方法目的就是自定义代码存储在run方法中,让线程运行。

    public class ThreadDemo extends Thread { /** * 覆写run方法 */ @Override public void run() { System.out.println("ThreadDemo is run"); } public static void main(String[] args) { new ThreadDemo().start(); } }

    start方法创建一个新的线程并执行该线程的run方法。

    { /** * This method is not invoked for the main method thread or "system" * group threads created/set up by the VM. Any new functionality added * to this method in the future may have to also be added to the VM. * * A zero status value corresponds to state "NEW". */ if (threadStatus != 0) throw new IllegalThreadStateException(); /* Notify the group that this thread is about to be started * so that it can be added to the group's list of threads * and the group's unstarted count can be decremented. */ group.add(this); boolean started = false; try { start0(); started = true; } finally { try { if (!started) { group.threadStartFailed(this); } } catch (Throwable ignore) { /* do nothing. If start0 threw a Throwable then it will be passed up the call stack */ } } }

    主要是调用了private native void start0() 创建线程然后由虚拟机来执行run方法。 1.2 实现Runnable接口

    public class public void run() { if (target != null) { target.run(); } } { public static void main(String[] args) { /** * 创建线程对象时候要明确要运行的代码 */ Thread thread = new Thread(new RunnableDemo()); thread.start(); } } class RunnableDemo implements Runnable { public void run() { System.out.println("RunnableDemo run method"); } }

    Thread类中run方法,其中target是创建Thread类时候Runnable接口实现类

    public void run() { if (target != null) { target.run(); } }

    2 多线程安全问题

    2.1同步代码块 synchronized (对象) { //需要同步的代码块 } 同步方法锁是this对象 如果该方法被static修饰,同步锁是该类字节码文件对象即:类名.class 同步前提: 1.必须要有两个或者两个以上的线程(单线程不需要同步) 2.必须多个线程使用同一个锁 3.哪些语句在操作共享数据就需要同步。 好处:解决了线程安全问题 弊端:多个线程需要判断锁,较为消耗资源 线程不安全实例

    public class ThreadDemo { public static void main(String[] args) { RunnableDemo runnableDemo = new RunnableDemo(); Thread thread1 = new Thread(runnableDemo); Thread thread2 = new Thread(runnableDemo); thread1.start(); thread2.start(); } } class RunnableDemo implements Runnable { /** * 多线程共享数据 */ private int index = 2000; public void run() { while (true) { if (index <= 0) { break; } System.out.println(Thread.currentThread().getName() + "index:" + index--); } } }

    使用同步代码块的

    public class ThreadDemo { public static void main(String[] args) { RunnableDemo runnableDemo = new RunnableDemo(); Thread thread1 = new Thread(runnableDemo); Thread thread2 = new Thread(runnableDemo); thread1.start(); thread2.start(); } } class RunnableDemo implements Runnable { /** * 多线程共享数据 */ private int index = 2000; public void run() { while (true) { if (index <= 0) { break; } synchronized (this) { System.out.println(Thread.currentThread().getName()+"index:" + index--); } } } }

    Java.util.concurrent.locks包定义了两个锁类,ReentrantLock和ReentrantReadWriteLock类。下面给出使用ReentrantLock实例。

    public class ThreadDemo { public static void main(String[] args) { RunnableDemo runnableDemo = new RunnableDemo(); Thread thread1 = new Thread(runnableDemo); Thread thread2 = new Thread(runnableDemo); thread1.start(); thread2.start(); } } class RunnableDemo implements Runnable { /** * 多线程共享数据 */ private int index = 2000; private ReentrantLock lock = new ReentrantLock(); public void run() { while (true) { if (index <= 0) { break; } try { lock.lock(); System.out.println(Thread.currentThread().getName() + "index:" + index--); } catch (Exception ex) { System.out.println(ex.getCause()); } finally { lock.unlock(); } } } }
    转载请注明原文地址: https://ju.6miu.com/read-33573.html

    最新回复(0)