JavaSE基础---多线程
Posted 猪八戒1.0
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaSE基础---多线程相关的知识,希望对你有一定的参考价值。
一:进程的概念
只有一个CPU,是怎么同时运行程序的呢?
把CPU的执行时间分成很多小块,每小块的时间都是固定的,把一个小块叫做时间片,时间片的时间可以非常短
二:创建多线程
(1)继承Thread
1.线程不能重复启动,否则会报错,主函数也是一个线程,会先执行主函数的线程再执行其他线程。调用start()方法即会执行run()方法。
测试:
//只能有一个public类,故未加public
class MyThread extends Thread
public void run()
//由于继承了Thread类,可以不通过对象直接调用getName()方法
System.out.println(getName()+"该线程被执行");
public class TestThread
public static void main(String[] args)
MyThread mt=new MyThread();
mt.start();//启动线程
System.out.println("主线程");
运行结果:
2.线程获取CPU的使用权是随机的,每次运行结果会不同
测试:
class MyThread extends Thread
public MyThread(String name)
//调用父类Thread的构造函数
super(name);
public void run()
for (int i = 1; i <=5 ; i++)
System.out.println(getName()+"正在运行"+i);
public class TestThread
public static void main(String[] args)
MyThread mt1=new MyThread("进程1");
MyThread mt2=new MyThread("进程2");
mt1.start();//启动线程
mt2.start();
运行结果:
(2)Runnable接口
extends 是继承父类,只要那个类不是声明final或者定义为abstract就能继承,Java中不支持多重继承,继承只能继承一个类,但implements可以实现多个接口,用逗号分开就行了。由于Runnable是接口,故用implements在其前。构建的类PrintRunnable创建的对象没有start()方法,需要通过Thread类创建对象。
测试:
class PrintRunnable implements Runnable
public void run()
for (int i = 1; i <=5 ; i++)
System.out.println(Thread.currentThread().getName()+"正在运行"+i);
public class TestRunnable
public static void main(String[] args)
PrintRunnable pr1=new PrintRunnable();
PrintRunnable pr2=new PrintRunnable();
Thread t1=new Thread(pr1);
Thread t2=new Thread(pr2);
t1.start();
t2.start();
Thread-0、Thread-1是系统自定义的线程名
运行结果:
三:线程的生命周期
join抢先执行 ,不使用原本随机执行
测试
class MyThread extends Thread
public void run()
for (int i = 1; i <=5 ; i++)
System.out.println(getName()+"正在执行"+i+"次!");
public class TestJoin
public static void main(String[] args)
MyThread mt=new MyThread();
mt.start();
//不抛出或者使用try carch 报错
try
mt.join();
catch (InterruptedException e)
e.printStackTrace();
for (int i = 1; i <5 ; i++)
System.out.println("主进程正在执行"+i+"次!");
运行
实际上使用Sleep对应休眠时间之后,是处于可运行阶段再去获取CPU资源,实际上的时间是大于休眠的时间的 。当两个对象时,运行结果交替运行的概率比较大,由于一个对象执行方法后休眠,此时另一个对象获取CPU资源的概率比较大。
测试1
sleep(1000) 每次执行隔1000ms
class MyThread implements Runnable
public void run()
for (int i = 1; i <=5 ; i++)
try
Thread.sleep(1000);
catch (InterruptedException e)
e.printStackTrace();
System.out.println(Thread.currentThread().getName()+"正在执行"+i+"次!");
public class TestSleep
public static void main(String[] args)
MyThread mt=new MyThread();
Thread t=new Thread(mt);
t.start();
System.out.println("主进程执行");
运行:
测试2
class MyThread implements Runnable
public void run()
for (int i = 1; i <=5 ; i++)
try
Thread.sleep(1000);
catch (InterruptedException e)
e.printStackTrace();
System.out.println(Thread.currentThread().getName()+"正在执行"+i+"次!");
public class TestSleep
public static void main(String[] args)
MyThread mt=new MyThread();
Thread t1=new Thread(mt);
t1.start();
Thread t2=new Thread(mt);
t2.start();
运行:
线程优先级的设置与操作系统的环境以及CPU的调度方式都是有关系的,所以结果不能完全把握优先级高的线程一定先执行,运行结果还是具有随机性的
测试:
class MyThread extends Thread
private String name;
public MyThread(String name)
this.name=name;
public void run()
for (int i = 1; i <=5 ; i++)
System.out.println(name+"正在执行"+i+"次!");
public class TestSleep
public static void main(String[] args)
int mainPriority=Thread.currentThread().getPriority();
System.out.println("主函数的优先级是"+mainPriority);
MyThread mt=new MyThread("线程1");
mt.setPriority(Thread.MAX_PRIORITY);
//等价 mt.setPriority(10);
mt.start();
System.out.println("线程1的优先级是"+mt.getPriority());
运行:
四.线程同步
同步的关键字可以确保对象共享,共享对象在同一时刻只能被一个线程访问。可以称做线程同步或者线程互斥
五.线程间通信
有生产后才能消费,若一生产一消费,由于线程运行的随机性,会出现没有生产时消费的情况,需要配合进程同步,wait(),notifyAll()等方法解决
测试:
Queue类
public class Queue
private int n;
boolean flag=false;
public synchronized int get()
if(!flag)
try
wait();
catch (InterruptedException e)
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("消费:"+n);
flag=false;//消费完毕,容器中没有数据
notifyAll();
return n;
public synchronized void set(int n)
if(flag)
try
wait();
catch (InterruptedException e)
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("生产:"+n);
this.n = n;
flag=true;//生产完毕,容器中已经有数据
notifyAll();
Producer类
public class Producer implements Runnable
Queue queue;
Producer(Queue queue)
this.queue=queue;
@Override
public void run()
int i=0;
while(true)
queue.set(i++);
try
Thread.sleep(1000);
catch (InterruptedException e)
// TODO Auto-generated catch block
e.printStackTrace();
Consumer类
public class Consumer implements Runnable
Queue queue;
Consumer(Queue queue)
this.queue=queue;
@Override
public void run()
while(true)
queue.get();
try
Thread.sleep(1000);
catch (InterruptedException e)
// TODO Auto-generated catch block
e.printStackTrace();
开发者涨薪指南
48位大咖的思考法则、工作方式、逻辑体系
以上是关于JavaSE基础---多线程的主要内容,如果未能解决你的问题,请参考以下文章