1.多线程描述-
Java 提供了三种创建线程的方法:
通过实现 Runnable 接口;
通过继承 Thread 类本身;
通过 Callable 和 Future 创建线程
3种创建线程的比较
线程的生命周期
2.代码
2.1.1 Callable实现多线程
public class MyCallable implements Callable {
@Override
public Integer call() throws Exception {
//求1~10@之间的和
int sum = 0;
for (int i = 1; i <= 100; i++) {
sum = sum + i;
}
return sum;
}
}
public static void main(String[] args) throws ExecutionException(){
/*
多线程的第三种实现方式:
特点:可以获取到多线程运行的结果
学
关
1.创建一个类MyCallable实现callable接口
2,重写cal (是有返回值的,表示多线程运行的结果)
装
3。创建MyCallable的对象(表示多线程要执行的任务)4。创建FutureTask的对象 (作用管理多线程运行的结果)
5,创建Thread类的对象,并启动(表示线程)
*/
//创建MyCallable的对象(表示多线程要执行的任务)
MyCallable mc = new MyCallable();//创建FutureTask的对象 (作用管理多线程运行的结果)
FutureTask ft = new FutureTask<>(mc);//创建线程的对象
Thread t1 = new Thread(ft);//启动线程
t1.start();//获取多线程运行的结果Integer result = ft.get();
System.out.printIn(result);
}
2.1.2 Runnable[实现多线程
public class MyRun implements Runnable{
@Override
public void run() {//书写线程要执行的代码
for (int i =;i<10; i++) {//获取到当前线程的对象
Thread t = Thread.currentThread();
System.out.println(t.getName() + "Helloworld!");
}
}
}
public class ThreadDemo {
public static void main(String[] args) {
/多线程的第二种启动方式:
1.自己定义一个类实现Runnable接口
2.重写里面的run方法
3.创建自己的类的对象
4.创建一个Thread类的对象,并开启线程/
//创建MyRun的对象//表示多线程要执行的任务
MyRun mr = new MyRun();
//创建线程对象
Thread t1 = new Thread(mr);
Thread t2 = new Thread(mr);
//给线程设置名字
tl.setName("线程1");
t2.setName("线程2");
//开启线程t1.start();
t2.start();
}
}
2.1.2 继承 Thread 类实现多线程
public class MyThread extends Thread{
@override
public void run() {
//书写线程要执行代码
for (int i = @; i< 10; i++) {
System.out.println(getName() + "HelloWorld");
}
}
}
public class ThreadDemo {
public static void main(String[] args) {
/**多线程的第一种启动方式:
1.自己定义一个类继承Thread
*
*2,重写run方法
*3,创建子类的对象,并启动线程
* */
MyThread t1 = new MyThread();
MyThread t2 = new MyThread();
t1.setName("线程1");
t2.setName("线程2");
t1.start();
t2.start();
}
}
3.常见的成员方法
3.1.1 设置线程的优先级(多线程中那个线程先执行)
public class MyRunnable implements Runnable{
@Override
for (int i = 1; i <= 100; i++) {
System.out.println(Thread.currentThread().getName();
}
}
public class ThreadDemo {
public static void main(String[] args){
//线程默认优先级是5
//设置线程的优先级
setPriority(int newPriority)
//获取线程的优先级
final int getPriority()
//创建线程要执行的参数对象
MyRunnable mr = new MyRunnable();
//创建线程对象
Thread t1 = new Thread(mr, name:"飞机");
Thread t2 = new Thread(mr, name: "如克");
tl.setPriority(1);t2.setPriority(1);
t1.start();t2.start();
}
}
3.1.2 设置线程详细参数
String getName() 返回此线程的名称
void setName(String name) 设置线程的名字(构造方法也可以设置名字)
1、如果我们没有给线程设置名字,线程也是有默认的名字的(格式: Thread-X (X序号,从e开始的))
2、如果我们要给线程设置名字,可以用set方法进行设置,也可以构造方法设置
3、获取当前线程的对象 static Thread currentThread()
说明:当JVM虚拟机启动之后,会自动的启动多条线程其中有一条线程就叫做main线程他的作 用就是去调用main方法,并执行里面的代码在以前,我们写的所有的代码,其实都是运 行在main线程当中
4、让线程休眠指定的时间,单位为毫秒 static void sleep(long time)
说明:1、哪条线程执行到这个方法,那么哪条线程就会在这里停留对应的时间
2、方法的参数:就表示睡眠的时间,单位毫秒1 秒= 10毫秒 Thread.sleep(10)
3、当时间到了之后,线程会自动的醒来,继续执行下面的其他代码
4.1 【守护线程】--通俗讲就是 “备胎”线程
守护线程说明:当其他非守护 线程执行完之后,守护线程会陆续结束
通俗的讲:当代码中的 “女神”线程结束了,“备胎线程”没有存在的必要了,也会立即结束线程
代码
public class ThreadDemo {
public static void main(String[] args) {
//设置为守护线程
//final void setDaemon(boolean on)
MyThread1 t1 = new MyThread1();
MyThread2 t2 = new MyThread2();
tl.setName("女神");
t2.setName("备胎");
//把第二个线程设置为守护线程(备胎线程)
t2.setDaemon(true);
t1.start();
t2.start();
}
}
5 插入线程/插队线程
public class ThreadDemo {
public static void main(String[] args) throws Interrupted {
//public final void join() 插入线程/插队线程
MyThread t = new MyThread();
t.setName("上豆");
t.start();
//表示把t这个线程,插入到当前线程之前。
//t:土豆
//当前线程: main线程
t.join();
//执行在main线程当中的
for (int i = @; i< 10; i++) {
System.out.println("main线程"+ i);
}
}
}
6.出让线程
...
7.线程安全
买票案例:
说明:某电影院目前正在上映国产大片,共有1张票,而它有3个窗口卖票,请设计一个
程序模拟该电影院卖票利用同步方法完成
技巧:同步代码块
解决办法:就是把synchronized关键字加到方法上
7.1 同步方法
7.2 同步代码块
public class MyThread extends Thread{
//表示这个类所有的对象,都共享ticket数据
static int ticket = 0;//日 ~ 99
//锁对象,一定要是唯一的
static Object obj = new object();
@Override
public void run() {
while (true){
//同步代码块
synchronized ( obj ){
if(ticket < 100 ){
try {
Thread.sleep( millis: 1);
catch (InterruptedException e) {
e.printStackTrace();
}
ticket++;
System.out.println(getName() +"正在卖第”+ ticket +"张票!!!");
}else{
break;
}
}
}
}
}