多线程介绍:
多线程是java中的一个并发的概念:
在计算机的运行中,所有的进程都是同时运行的(cpu会同时调用,之后随机的获取分配)
1.在java程序中也是支持的!
2.在java执行main方法的时候,其实就是执行一个名字叫做main的线程,可以在main线程执行的时候,开启多个其他的线程A,B,C等等,多个线程A,B,C等等都是同时执行的,同时等等cpu的调用,相互抢夺cpu调用自己的时间片段。
3.Thread类是java中的专门用于处理线程的api,是java.lang下的常用类,每一个Thread类的对象,
就代表一个某种状态的线程。
java.lang包下的常用的类有:String,System,八大基本类型,Thread…
进程:表示一个个的正在运行的程序,比如qq,qq音乐,网易云…
- 线程:表示一个个正在运行程序中的子进程(线程),qq的聊天窗口
- 包含关系:一个进程包含多个进程
- java中的线程是支持多线程的,多个线程可以同时进行,但是不能保证(控制)线程的运行,具体是看CPU的调用,我们只能看到结果。
java中使用Thread类来创建线程
第一种方式:
步骤:
- 1.指定执行线程的目标:定义一个Thread子类,重写run方法,将相关的逻辑实现,public void run():将需要的逻辑写在里面,该方法相当于线程中的main方法。
- 2.创建自定义线程的子类对象
3.开启线程操作 - 触发
public void start():只要调用了这个方法,线程才会启动,开始执行
Thread中的相关方法:
- public final String getName():获取线程的名称
- public final void setName():设置线程的名字
- public static Thread currentThread():获取当前的线程对象

线程的运行默认是不可控制的,是cpu随机调用,我们只能看到运行的结果。
**
package ThreadDemo1;/*** 自定义线程类* 定义一个Thread的子类!** 创建线程的第一种方式:继承Thread类*/public class MyThread extends Thread{//重写run方法 - 相关的逻辑写进去@Overridepublic void run(){for (int i = 0; i < 50; i++) {/*this表示当前正在被调用的这个线程获取线程的名字是java干的事情(java定义的),我们不管,只要看就行了*/System.out.println(this.getName()+":"+i);}}}
package ThreadDemo1;public class ThreadDemo1 {//主线程public static void main(String[] args) {//创建线程对象 - 用于开启线程Thread t0 = new MyThread();Thread t1 = new MyThread();//开启线程 - 直接运行t0.start();t1.start();System.out.println("===========================");//返回一个main线程 - 其实就是main方法的线程Thread mainThread = Thread.currentThread();System.out.println(mainThread);//Thread[main,5,main]for (int i = 0; i < 50; i++) {System.out.println(mainThread.getName()+":"+i);}}}
start()方法的作用1.启动当前线程2.调用当前线程的run()
第二种方式:实现Runnable接口
- 1.实现接口,并且要实现run方法
- 2.在run方法中添加逻辑代码
- 3.通过start启动线程
```java
package ThreadDemo1;
/**
创建线程的第二种方式: */ public class MyRunnable implements Runnable{
@Override public void run() {
//返回当前线程Thread thisThread = Thread.currentThread();
} }
**步骤:**- 1.指定线程执行的目标:定义Runnable接口,并且实现接口,重写run方法,指定目标逻辑- 2.通过指定线程执行目标的构造方法创建线程对象- public Thread(Runnable target)- 1)创建线程,并且执行目标对象- 2)通过线程执行目标对象创建线程对象- 3.开启线程操作(start)**好处:将任务和线程相分离,耦合度比较低,使用也更加的广泛。**```javapackage ThreadDemo1;/*** java中使用Thread类来创建线程:语法*第二种方式:**/public class ThreadDemo2 {//主线程public static void main(String[] args) {//创建线程执行目标MyRunnable mr = new MyRunnable();//线程对象 - 任务//通过指定线程执行目标的构造函数来创建线程Thread thread = new Thread(mr);//线程名称thread.setName("jack");Thread thread2 = new Thread(mr);//线程名称thread.setName("rose");//开启线程thread.start();thread2.start();}}
线程的优先级

说明:高优先级的线程要抢占低优先级线程的CPU执行权。但是只是 从概率上讲,高优先级的线程高概率
会被执行,并不意味着只有高优先级执行完后,低优先级才会执行。
**
匿名内部类创建线程 - 实际开发中使用
- 1.使用匿名内部类创建线程的原理和普通类创建线程原理完全一样。
- 2.区别在于利用匿名内部类创建线程的写法更加的简洁,使用非常多。 ```java package AnonysThread;
/**
- 匿名内部类创建线程 - 实际开发中使用 *
- 1.使用匿名内部类创建线程的原理和普通类创建线程原理完全一样。
2.区别在于利用匿名内部类创建线程的写法更加的简洁,使用非常多。 / public class AnonysThreadDemo { public static void main(String[] args) {
//方式一:使用匿名内部类创建线程的子类对象Thread t1 = new Thread(){@Overridepublic void run(){System.out.println("我很好");}};t1.start();System.out.println("-----------------------------------------------");//使用匿名内部类,创建线程的匿名子类对象,并且启动线程new Thread(){@Overridepublic void run(){System.out.println("还记得上次你我身旁的样子");}}.start();//方式二:使用匿名内部类的方式,创建执行目标类的对象Runnable r = new Runnable(){@Overridepublic void run(){System.out.println("她来了然后他死了");}};//传入到构造函数Thread t2 = new Thread(r);t2.start();System.out.println("==========================================");//组合写法 - 精简写法new Thread(new Runnable() {@Overridepublic void run() {System.out.println("往事只能后悔");}}).start();//t3的普通写法Thread t3 = new Thread(new Runnable() {@Overridepublic void run() {System.out.println("往事只能后悔");}});t3.start();
} }
**线程的生命周期**<br />****<br />****<br />**<br />**线程的安全问题**<br />****<br />**在java中我们通过同步机制来解决线程的安全问题**<br />****<br />**要求:多个线程必须共用一把锁**<br />**同步方法**<br />****<br />****<br />** 说明:这三个方法只能出现在同步代码块和同步方法中**<br />**这三个方法的调用者必须是同步代码快或同步方法中的同步监视器**<br /> 实现callable接口创建线程```javaimport java.util.concurrent.Callable;import java.util.concurrent.ExecutionException;import java.util.concurrent.FutureTask;/*** 创建线程的方式三:实现callable接口。------jdk5.0新增*///创建一个实现callable接口的实现类class CallableTest implements Callable {//实习call方法,将此线程需要执行的操作声明在call()方法中@Overridepublic Object call() throws Exception {int sum=0;for (int i = 0; i <= 100; i++) {if(i%2==0){System.out.println(i);sum+=i;}}return sum;}}public class ThreadNew{public static void main(String[] args) throws ExecutionException {//创建callable接口实现类对象CallableTest callableTest = new CallableTest();//将次callable接口实现类对象作为参数传递到FutureTask构造器中,创建FutureTask的对象FutureTask futureTask = new FutureTask(callableTest);//将FutureTask的对象作为参数传递到Thread类的构造器中,创建Thread对象,并调用start()方法new Thread(futureTask).start();try {//获取callable中call方法的返回值//get()方法的返回值即为FutureTask构造器参数callcable实现类重写call()的返回值Object sum = futureTask.get();System.out.println("总和是" + sum);} catch (InterruptedException e) {e.printStackTrace();}}}

使用线程池创建线程
Executors:工具类,线程池工厂类,用于创建并返回不同类型的线程池
ExecutorService:真正的线程池接口
class NumberThread implements Runnable{@Overridepublic void run() {for (int i = 0; i <= 100; i++) {if(i%2==0){System.out.println(Thread.currentThread().getName()+":"+i);}}}}class NumberThread1 implements Runnable{@Overridepublic void run() {for (int i = 0; i <= 100; i++) {if(i%2!=0){System.out.println(Thread.currentThread().getName()+":"+i);}}}}public class ThreadPoolTest {public static void main(String[] args) {//提供指定线程数量的连接池ExecutorService executorService = Executors.newFixedThreadPool(10);//设置线程池属性System.out.println(executorService.getClass());//执行指定线程的操作,需要提供实现Runnable接口或Callable接口实现类的对象executorService.execute(new NumberThread());//适合适用于RunnableexecutorService.execute(new NumberThread1());//executorService.submit();//适合使用于CallablleexecutorService.shutdown();//关闭连接池}}

**
