Java之线程
1.线程
实现线程的两种方法:
- 创建一个Thread类,或者一个Thread子类的对象
- 创建一个实现Runnable接口的类的对象
Thread类
Thread是一个线程类,位于java.lang包下
Thread类的常用方法
Runnable接口
- 只有一个方法run();
- Runnable是Java中用以实现线程的接口
- 任何实现线程功能的类都必须实现该接口(包括Thread类)
线程创建
通过继承Thread类的方式创建线程类,重写run()方法。
class MyThread extends Thread{
public void run() {
System.out.println(getName() + "这个线程正在运行 !");
}
}
public class TheadTest {
public static void main(String[] args) {
MyThread mt = new MyThread();
mt.start(); // 只能调用一次,线程不能被多次启动
}
}
输出结果:
线程的调用顺序是随机的
class MyThread extends Thread{
public MyThread(String name) {
super(name);
}
public void run() {
for (int i=1; i<=10; i++) {
System.out.println(getName() + "这个线程正在运行 !");
}
}
}
public class TheadTest {
public static void main(String[] args) {
MyThread mt1 = new MyThread("线程01");
MyThread mt2 = new MyThread("线程02");
mt1.start();
mt2.start();
}
}
输出结果:
从程序输出的结果可以看出线程的调用顺序是随机的。
通过实现Runnable接口的方式创建线程类
原因:
- Java不支持多继承,已经继承了其他类无法再继承线程类
- 不打算重写Thread类的其他方法
class RunnableTest implements Runnable{
int i;
public void run() {
for (i = 1; i<=10; i++) {
System.out.println(Thread.currentThread().getName() + "这个线程正在运行 !");
}
}
}
public class Test {
public static void main(String[] args) {
RunnableTest rt = new RunnableTest();
Thread tr1 = new Thread(rt);
tr1.start();
Thread tr2 = new Thread(rt); // 如果创建多个线程基于同一个Runnable target,即rt则所有线程共同执行其中的资源。
tr2.start();
}
}
输出结果:
线程的状态
线程分为五个状态
- 新建(new)
- 可运行(Runnable)
- 正在运行(Running)
- 阻塞(Blocked)
- 终止(Dead)
线程的生命周期
![截图来自慕课网](https://img-blog.csdnimg.cn/db7957e26e4b444abfc7ef26486618d2.png?x-oss-p
sleep方法
Thread类的方法
public static void sleep(long millis)
让正在执行的线程休眠指定的毫秒数。
class RunnableTest implements Runnable{
int i;
public void run() {
for (i = 1; i<=10; i++) {
System.out.println(Thread.currentThread().getName() + "这个线程正在运行 !");
if(i == 3) {
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
public class Test {
public static void main(String[] args) {
RunnableTest rt1 = new RunnableTest();
Thread tr1 = new Thread(rt1);
tr1.start();
RunnableTest rt2 = new RunnableTest();
Thread tr2 = new Thread(rt2);
tr2.start();
}
}
输出结果:
join方法
Thread类的方法
public final void join()
public final void join(long millis)
优先执行调用该方法的线程,等该线程结束之后再执行其他的线程
可以穿入参数,long millis为最长等待时间。
class RunnableTest implements Runnable{
int i;
public void run() {
for (i = 1; i<=10; i++) {
System.out.println(Thread.currentThread().getName() + "这个线程正在运行 !");
}
}
}
public class Test {
public static void main(String[] args) {
RunnableTest rt1 = new RunnableTest();
Thread tr1 = new Thread(rt1);
tr1.start();
try {
tr1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
RunnableTest rt2 = new RunnableTest();
Thread tr2 = new Thread(rt2);
tr2.start();
}
}
输出结果:
线程的优先级
从数字1到10,越大优先级越高,默认优先级为5。
优先级常量
- MAX_PRIORITY: 线程的最高优先级10
- MIN_PRIORITY: 线程的最低优先级1
- NORM_PRIORITY:线程的默认优先级5
注:线程优先级高并不一定先执行,具有一定的随机性
public int getPriority()
public void setPriority(int newPriority)
class RunnableTest implements Runnable{
int i;
public void run() {
for (i = 1; i<=10; i++) {
System.out.println(Thread.currentThread().getName() + "这个线程正在运行 !");
}
}
}
public class Test {
public static void main(String[] args) {
RunnableTest rt1 = new RunnableTest();
Thread tr1 = new Thread(rt1);
RunnableTest rt2 = new RunnableTest();
Thread tr2 = new Thread(rt2);
tr1.setPriority(Thread.MAX_PRIORITY);
tr1.start();
tr2.start();
System.out.println("线程:"+tr1.getName()+"的优先级为:"+tr1.getPriority());
System.out.println("线程:"+tr2.getName()+"的优先级为:"+tr2.getPriority());
}
}
输出结果:
线程同步
synchronized关键字
作用领域:
- 成员方法
- 静态方法
- 语句块
public synchronized void saveAccount(){}
public static synchronized void saveAccount(){}
synchronized (object){}
class RunnableTest implements Runnable{
int i;
public void run() {
synchronized(this) {
for (i = 1; i<=10; i++) {
System.out.println(Thread.currentThread().getName() + "这个线程正在运行 !");
}
}
}
}
public class Test {
public static void main(String[] args) {
RunnableTest rt1 = new RunnableTest();
Thread tr1 = new Thread(rt1);
RunnableTest rt2 = new RunnableTest();
Thread tr2 = new Thread(rt1);
tr1.start();
tr2.start();
}
}
输出结果:
可以看到,相同的对象被锁住,第一个线程执行完成,第二个线程才会执行。
如果对象不同,则锁失效。
class RunnableTest implements Runnable{
int i;
public void run() {
synchronized(this) {
for (i = 1; i<=10; i++) {
System.out.println(Thread.currentThread().getName() + "这个线程正在运行 !");
}
}
}
}
public class Test {
public static void main(String[] args) {
RunnableTest rt1 = new RunnableTest();
Thread tr1 = new Thread(rt1);
RunnableTest rt2 = new RunnableTest();
Thread tr2 = new Thread(rt2);
tr1.start();
tr2.start();
}
}
输出结果:
线程间的通信
方法:
- wait(): 使线程中断执行,进入阻塞状态
- notify(): 唤醒某一个等待的线程
- notifyAll(): 唤醒所有等待的线程
public class Queue {
private int n;
Boolean flag = false;
public synchronized int getN() {
if(!flag) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("消费:"+n);
flag = false;
notifyAll();
return n;
}
public synchronized void setN(int n) {
if(flag) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("生产:"+n);
flag = true;
notifyAll();
this.n = n;
}
}
public class Producer implements Runnable {
Queue queue;
Producer(Queue queue){
this.queue= queue;
}
@Override
public void run() {
int i=0;
while(true) {
queue.setN(i++);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Consumer implements Runnable {
Queue queue;
Consumer(Queue queue){
this.queue= queue;
}
@Override
public void run() {
int i=0;
while(true) {
queue.getN();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Test {
public static void main(String[] args) {
Queue queue=new Queue();
new Thread(new Producer(queue)).start();
new Thread(new Consumer(queue)).start();
}
}
输出结果: