Java 多线程基础

并行:只两个或多个事件同一时刻点发生;多个cpu实例或者多台机器同时执行一段处理逻辑,是真正的同时。
并发:只两个或多个事件同一时间段内发生;通过cpu调度算法,让用户看上去同时执行,实际上从cpu操作层面不是真正的同时。并发往往在场景中有公用的资源,那么针对这个公用的资源往往产生瓶颈,我们会用TPS或者QPS来反应这个系统的处理能力。

创建一个线程

Java 提供了三种创建线程的方法:
通过实现 Runnable 接口;
通过继承 Thread 类本身;
通过 Callable 和 Future 创建线程。

三种多线程实现方式

多线程的两种实现方式的区别

Thread 类是Runnable 接口的子类,使用Runnable接口实现多线程可以避免单继承局限

Runnable接口多线程可以比Thread类实现的多线程更加清楚的描述数据共享,此时的数据共享指的是多个线程访问同一个资源操作

启动线程使用start(),不使用run(),因为使用Thread类的start()方法不仅仅要启动多线程的执行代码,【包含start0()】还会去根据当前系统去分配资源

实现方式

1, Runnable接口实现

/**
 * Created by Jasonote on 2017/8/22.
 */
class MyThread2 implements Runnable {
    private int tickert = 10;
    @Override
    public void run() {
        for (int x = 0; x < 100; x++) { if(this.tickert > 0) {
                System.out.println("卖票--->" + this.tickert --);
            }
        }
    }
}

public class Thread02 {
    public static void main(String[] args) {
        MyThread2 mt1 = new MyThread2();
        new Thread(mt1).start();
        new Thread(mt1).start();
        new Thread(mt1).start();
    }
}

2,Thread继承实现

class MyThread extends Thread {
    private String name;
    public MyThread(String name) {
        this.name = name;
    }

    @Override
    public void run() {
        for (int x = 0; x < 10; x++) { System.out.println(this.name + "--->" + x);
        }
    }
}

public class Thread01 {
    public static void main(String[] args) {
        System.out.println("thread ....");
        MyThread mt1 = new MyThread("thread1");
        MyThread mt2 = new MyThread("thread2");
        MyThread mt3 = new MyThread("thread3");
        mt1.start();
        mt2.start();
        mt3.start();
    }
}

3,Thread继承实现

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

/**
 * Created by Jasonote on 2017/8/22.
 */
class MyThread3 implements Callable<String> {
    private int tickert = 10;

    @Override
    public String call() throws Exception {
        for (int x = 0; x < 100; x++) { if(this.tickert > 0) {
                System.out.println("卖票--->" + this.tickert --);
            }
        }

        return "票已经卖光";
    }
}

public class Thread03 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        MyThread3 mt1 = new MyThread3();
        MyThread3 mt2 = new MyThread3();
        FutureTask<String> task = new FutureTask(mt1);
        FutureTask<String> task2 = new FutureTask(mt2);

        new Thread(task).start();
        new Thread(task2).start();

        System.out.println("A:"+task.get());
        System.out.println("B:"+task.get());
    }
}

Q:每一个JVM进程启动的时候至少启动几个线程?
·main线程:程序的主要执行,已经启动子线程
·gc线程:负责垃圾收集

线程的休眠

线程优先级
所谓的优先级指的是越高的优先级,越有可能执行。
· 设置优先级:public final void setPriority(int newPriority);
· 取得优先级:public final int getPriority();
发现设置和取得优先级都是使用了int数据类型,对于此内容有三种取值
·最高优先级:public static final int MAX_PRIORITY;
·中级优先级:public static final int NORM_PRIORITY;
·最低优先级:public static final int MIN_PRIORITY;

线程的同步
在Java里面实现线程的同步可以使用 synchronized 关键字
·一种是同步代码块
·一种是同步方法
在Java里面有四种代码块:普通代码块,构造块,静态块,同步块

Q:请解释多个线程访问同一资源时需要考虑到那些情况?有可能带来哪些问题?
·多个线程访问同一资源时一定要处理好同步,可以使用同步代码块或同步方法
|- 同步代码块: synchronized(锁定对象){code}
|- 同步方法: public synchronized 返回值 methodName(){code}
·但是过多的使用同步,有可能造成死锁

使用ExecutorService、Callable、Future实现有返回结果的多线程
多线程后续会学到,这里暂时先知道一下有这种方法即可。

ExecutorService、Callable、Future这个对象实际上都是属于Executor框架中的功能类。想要详细了解Executor框架的可以访问 ,这里面对该框架做了很详细的解释。返回结果的线程是在JDK1.5中引入的新特征,确实很实用,有了这种特征我就不需要再为了得到返回值而大费周折了,而且即便实现了也可能漏洞百出。

Jason.wang

When you find your talent can't afford to be ambitious, be quiet and study !

You may also like...