java多线程基础
Posted 知道什么是码怪吗?
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java多线程基础相关的知识,希望对你有一定的参考价值。
目录
实现多线程的两种基础方式
方式一:继承Thread类
java中一个类只能继承一个父类,如果当前类已经继承了其他类了,则不能使用这种方法。
class Way1 extends Thread
private boolean bool = true;// 用于控制进程结束
public void run() // 编写具体的逻辑代码
while (bool)
System.out.println("way1线程执行" + " 线程名为:" + Thread.currentThread().getName());
try
Thread.sleep(100);// 睡眠0.1秒
catch (InterruptedException e)
e.printStackTrace();
public boolean isBool() // 可用于查看线程的状态
return bool;
public void setBool(boolean bool) // 可用于改变线程的状态
this.bool = bool;
public class Text1
public static void main(String[] args) throws InterruptedException
Way1 way1 = new Way1();
way1.start();
Thread.sleep(5000);// 主线程睡眠5秒,这个时候子线程仍然在执行
way1.setBool(false);// 然后关闭线程
方式二:实现Runnable接口
避免了方式一的问题,但是在开启线程的时候代码实现略有不同。
class Way2 implements Runnable
private boolean bool = true;// 用于控制进程结束
@Override
public void run() // 编写具体的逻辑代码
while (bool)
System.out.println("way2线程执行" + " 线程名为:" + Thread.currentThread().getName());
try
Thread.sleep(100);// 睡眠0.1秒
catch (InterruptedException e)
e.printStackTrace();
public boolean isBool() // 可用于查看线程的状态
return bool;
public void setBool(boolean bool) // 可用于改变线程的状态
this.bool = bool;
public class Text1
public static void main(String[] args) throws InterruptedException
Way2 way2 = new Way2();
Thread thread = new Thread(way2);
thread.start();// new Thread(way2).start();
Thread.sleep(5000);// 主线程睡眠5秒,这个时候子线程仍然在执行
way2.setBool(false);// 然后关闭线程
线程常用方法
线程优先级设置
// 线程优先级为1~10,不在范围内会抛出异常
// 设置优先级 setPriority();
// 获取优先级 getPriority();
System.out.println(Thread.MAX_PRIORITY);// 最高优先级:10
System.out.println(Thread.NORM_PRIORITY);// 一般优先级:5
System.out.println(Thread.MIN_PRIORITY);// 最低优先级:1
// 对于方式1实现的多线程
Way1 way1 = new Way1();
way1.setPriority(10);// 设置优先级
System.out.println(way1.getPriority());// 查看优先级
// 对于方式2实现的多线程
Way2 way2 = new Way2();
Thread thread = new Thread(way2);
thread.setPriority(5);
System.out.println(way1.getPriority());// 查看优先级
线程的插队和礼让
// 线程的礼让: Thread.yield(); 该方法为静态方法,不一定礼让成功。如果资源充足礼让不成功
// 线程的插队: 类名.join(); 插队成功后先执行完插入的线程的所有任务,再执行当前线程
// 获取电脑核数:Runtime.getRuntime().availableProcessors();
class Way1 extends Thread
private boolean bool = true;// 用于控制进程结束
private int count = 0;// 记录执行次数
@Override
public void run() // 编写具体的逻辑代码
while (bool)
System.out.println((++count) + " way1线程执行" + " 线程名为:" + Thread.currentThread().getName());
if (count == 15)
break;
try
Thread.sleep(100);// 睡眠0.1秒
catch (InterruptedException e)
e.printStackTrace();
public boolean isBool() // 可用于查看线程的状态
return bool;
public void setBool(boolean bool) // 可用于改变线程的状态
this.bool = bool;
public class Text1
public static void main(String[] args) throws InterruptedException
Way1 way1 = new Way1();
way1.start();
for (int i = 1; i <= 10; i++)
Thread.sleep(100);
System.out.println(i + " 主线程执行" + " 线程名为:" + Thread.currentThread().getName());
if (i == 5)
way1.join();//**本来同时执行,让way1插队先执行**
运行结果:
线程的中断
//线程中断: 类名.interrupt(); 不是中止是中断
class Way1 extends Thread
private boolean bool = true;// 用于控制进程结束
private int count = 0;
@Override
public void run() // 编写具体的逻辑代码
while (bool)
for (int i = 1; i <= 5; i++) // 输出5次停20秒
System.out.println((i) + " way1线程执行" + " 线程名为:" + Thread.currentThread().getName());
try
Thread.sleep(200000);//停200秒
catch (InterruptedException e)
System.out.println("捕获中断");
public boolean isBool() // 可用于查看线程的状态
return bool;
public void setBool(boolean bool) // 可用于改变线程的状态
this.bool = bool;
public class Text1
public static void main(String[] args) throws InterruptedException
Way1 way1 = new Way1();
way1.start();
for (int i = 1; i <= 10; i++)
Thread.sleep(5000);//5秒过后
way1.interrupt();//**提前结束休眠再次启动**
运行结果:
守护线程
/*
* 设置守护线程: 类名.setDaemon(); 当主线程下有子线程时 如果子线程可以无限的执行,那么当主线程执行结束后,子线程并不会结束。
* 如果我们想子线程随着主线程一同结束,就要设置为守护线程
*/
class DaemonThread extends Thread
private boolean bool = true;// 用于控制进程结束
private int count = 0;
@Override
public void run() // 编写具体的逻辑代码
while (bool)
System.out.println((++count) + " 子线程执行" + " 线程名为:" + Thread.currentThread().getName());
try
Thread.sleep(1000);
catch (InterruptedException e)
e.printStackTrace();
public boolean isBool() // 可用于查看线程的状态
return bool;
public void setBool(boolean bool) // 可用于改变线程的状态
this.bool = bool;
public class Text1
public static void main(String[] args) throws InterruptedException
DaemonThread dt = new DaemonThread();
dt.setDaemon(true);//**设置为守护线程,当主线程结束时子线程一同结束**
dt.start();
for (int i = 1; i <= 5; i++)
System.out.println((i) + " 主线程执行" + " 线程名为:" + Thread.currentThread().getName());
Thread.sleep(1000);// 5秒过后
运行结果:
线程同步
多线程时间比较
通过使用欧拉筛求素数、朴素方法求素数、多线程朴素方法求素数来进行时间比较,多线程消耗的时间是一个大概的值,不是准确的。因为在求素数的过程中,程序执行的太快了,多个线程有可能拿了同一个数做运算,这就导致多线程的运算量大于的朴素方法。
class GetPrime extends Thread
public static int count = 2;
public static int num = 0;// 记录素数个数
public int n;// 求素数的范围
long startTime;
long endTime;
public static boolean[] bool = new boolean[10000000];//减少重复计算
GetPrime(int n)
this.n = n;
@Override
public void run() // 编写具体的逻辑代码
while (count <= n) //多线程求素数的时候有可能count还没有加1,另一个线程拿了相同的数做比较,这样写是为了减少重复的计算,但仍然不彻底
if (bool[count] == false) //这个数没有拿过,拿过来标记为true
bool[count] = true;
int a = count;
count++;
if (Prime(a) == true)
num++;
else
count++;
endTime = System.currentTimeMillis(); // 获取开始时间
public static boolean Prime(int number) // 朴素方法求素数
for (int i = 2; i <= Math.sqrt(number); i++)
if (number % i == 0)
return false;
return true;
public class Text1
public static void GetPrime(int n) // 欧拉筛求素数,素数都被保留在prime数组当中
int[] prime = new int[n + 10];
boolean[] bool = new boolean[n + 10];
int count = 0;
for (int i = 2; i <= n; i++)
if (bool[i] == false)
prime[count++] = i;
bool[i] = true;
for (int j = 0; j < count; j++)
if (i * prime[j] > n)
break;
bool[i * prime[j]] = true;
if (i % prime[j] == 0)
break;
System.out.println(count);// 输出个数
public static boolean Prime(int number) // 朴素方法求素数
for (int i = 2; i <= Math.sqrt(number); i++)
if (number % i == 0)
return false;
return true;
public static void main(String[] args) throws InterruptedException
int count = 0;
int n = 1000000;
long startTime = System.currentTimeMillis(); // 获取开始时间
GetPrime(n);
long endTime = System.currentTimeMillis(); // 获取结束时间
System.out.println("欧拉筛程序运行时间:" + (endTime - startTime) + "ms"); // 输出程序运行时间
// 6977
startTime = System.currentTimeMillis(); // 获取开始时间
for (int i = 2; i <= n; i++)
if (Prime(i) == true)
count++;
System.out.println(count);// 输出个数
endTime = System.currentTimeMillis(); // 获取结束时间
System.out.println("朴素for循环程序运行时间:" + (endTime - startTime) + "ms"); // 输出程序运行时间
startTime = System.currentTimeMillis(); // 获取开始时间
GetPrime P1 = new GetPrime(n);
GetPrime P2 = new GetPrime(n);
GetPrime P3 = new GetPrime(n);
GetPrime P4 = new GetPrime(n);
P1.start();//开4个线程
P2.start();
P3.start();
P4.start();
Thread.sleep(1000);
System.out.println(GetPrime.num);// 输出个数
endTime = System.currentTimeMillis(); // 获取结束时间
System.out.println("朴素多线程for循环程序运行时间:" + (P1.endTime - startTime) + "ms"); // 输出程序运行时间
运行结果:
可以看到,多线程在做了许多重复的计算过后,消耗的时间仍然比朴素for循环快。
也可以看到,多线程没有欧拉筛快,说明算法对效率的提高是多么的大!!!
以上是关于java多线程基础的主要内容,如果未能解决你的问题,请参考以下文章