今天学了一点多线程,感觉有点乱乱的
一.有三种方法可以实现多线程
1.继承Thread类;
直接继承Thread类,重写run方法
package a0415;
//第一种执行方法(继承Thread类的方法进行实现)
public class Test1 {
public static void main(String[] args) {
//继承Thread类,重写run方法
MyThread t1=new MyThread();
MyThread t2=new MyThread();
t1.setName("线程1");
t2.setName("线程2");
//运行后能够看出来能够体现是随机交替执行
t1.start();
t2.start();
}
}
package a0415;
public class MyThread extends Thread{
@Override
public void run() {
//线程要做的事情
for (int i = 0; i < 100; i++) {
if(getName().equals("线程1")){
System.out.println("我在执行线程1");
}
if(getName().equals("线程2")){
System.out.println("我在执行线程2");
}
}
}
}
2.实现Runnable接口;
package a0415;
public class Test2 {
public static void main(String[] args) {
MyRunable mr=new MyRunable();
//把任务传递给线程
Thread t1=new Thread(mr);
Thread t2=new Thread(mr);
t1.setName("线程1");
t2.setName("线程2");
t1.start();
t2.start();
}
}
package a0415;
public class MyRunable implements Runnable{
@Override
public void run() {
//书写线程需要执行的语句
for (int i = 0; i < 100; i++) {
Thread t=Thread.currentThread();//这个是一个静态方法能够知道现在是哪个线程在运行
System.out.println(t.getName()+"运行的第"+i+"次。");
}
}
}
3.利用Callable接口和Future接口;
package a0415;
//利用Callable接口和Future接口实现
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class Test3 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
//创建MyCallable的对象(表示多线程要执行的任务)
MyCallable mc=new MyCallable();
//管理多线程运行的结果(要把任务传进去得到结果)
FutureTask<Integer> ft=new FutureTask<>(mc);
//创建线程对象
Thread t1=new Thread(ft);
//启动线程
t1.start();
//获得线程结果
Integer result= ft.get();
//输出线程结果
System.out.println(result);
}
}
package a0415;
import java.util.concurrent.Callable;
public class MyCallable implements Callable<Integer> {
@Override
public Integer call() throws Exception {
int sum=0;
for (int i = 0; i <= 100; i++) {
sum+=i;
}
return sum;
}
}
二.常见的几个方法
1.休眠(刚学感觉可以用在我之前的ATM系统里面做那个输错密码之后要几分钟再重输那里)
package a0415;
import java.util.Scanner;
//休眠
public class Test4 {
public static void main(String[] args) throws InterruptedException {
int count=0;
Scanner sc=new Scanner(System.in);
System.out.println("请输入你的密码");
while (true) {
String password=sc.next();
if(password.equals("12345")){
System.out.println("你输入的密码正确");
break;
}else{
count++;
if(count==3){
System.out.println("你已经连续三次输错密码请五秒后再试");
Thread.sleep(12000);
System.out.println("你可以重新输入你的密码了");
}else{
System.out.println("你的密码有误请再次输入你的密码");
}
}
}
}
}
但是运行的时候发现休眠的时候我还能不断输入我想输入什么就输入什么(暂时不知道怎么处理)
2.优先级
package a0415;
//优先级
public class Test5 {
public static void main(String[] args) {
MyRunable mr=new MyRunable();
Thread t1=new Thread(mr,"汽车");
Thread t2=new Thread(mr,"轮船");
System.out.println(t1.getPriority());
System.out.println(t2.getPriority());
t1.setPriority(1);
t2.setPriority(10);
/*测试之后发现优先级低并不是说一定要等优先级高的运行完之后才能运行
优先级只是一个概率,不是绝对的!!!!*/
t1.start();
t2.start();
}
}
3.守护线程
package a0415;
//守护线程!!!final void setDaemon(boolen on)
public class Test6 {
public static void main(String[] args) {
MyThread6 t1=new MyThread6();
MyThread602 t2=new MyThread602();
t1.setName("女神");
/*t2为备胎线程
* 当其他非守护线程结束以后,守护线程就会陆续结束
* 当t1执行完以后,t1就会告诉t2,你没有什么存在的必要了,在这个过程中t2还在运行所以t2还会运行一会*/
t2.setName("备胎");
t2.setDaemon(true);
t1.start();
t2.start();
}
}
/*应用场景:
* 你在微信和别人聊天的同时给别人发了一个文件,然后你关闭聊天窗口
* 文件传输这个线程就会陆续结束,也就是备胎线程*/
package a0415;
public class MyThread6 extends Thread{
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(getName()+"@"+i);
}
}
}
package a0415;
public class MyThread602 extends Thread{
@Override
public void run() {
for (int i = 0; i <= 100 ; i++) {
System.out.println(getName()+"@"+i);
}
}
}
4.出让线程
package a0415;
//出让线程public static void yield()
public class Test7 {
public static void main(String[] args) {
MyRunable mr=new MyRunable();
Thread t1=new Thread(mr,"汽车");
Thread t2=new Thread(mr,"轮船");
t1.start();
t2.start();
}
}
/*尽可能会让结果均匀一点,每执行一次都会抢一次但有可能还是上一次的那个抢到*/
5.插入线程
package a0415;
//插入线程
public class Test8 {
public static void main(String[] args) throws InterruptedException {
MyThread6 t=new MyThread6();
t.setName("飞机");
t.start();
//把飞机线程插入到main线程之前,让t先运行完再运行main;
t.join();
for (int i = 0; i < 10; i++) {
System.out.println("main线程"+i);
}
}
}