Java——多线程
多线程的用处:
- 处理需要执行多个任务的情况
- 处理需要等待的任务
- 处理需要后台运行的任务
多线程的生命周期:
实现多线程有两种方式:
- 继承Thread类,并重写run()方法
- 继承Runnable接口
1、继承Thread类实现多线程
下面这个程序实现了继承Thread的方法创建多线程,并且试用了Thread提供的常用方法:
package com.kexin.study;
public class TestMyThread {
public static void main(String[] args) throws InterruptedException {
MyThread mt = new MyThread();
//执行子线程,直接调用start()不影响主进程运行,
//但是调用run()就相当于调用普通重写方法,并没有启动多线程
//可以在start()之前设置线程的优先级,将改变该线程获得CPU控制权的概率
mt.setPriority(Thread.MAX_PRIORITY);
mt.start();
for(int i = 0;i<100;i++){
if(i%3==0){
//yield()方法是将该线程的CPU控制权主动让出
Thread.currentThread().yield();
}
if(i==10){
//join()方法会暂时停止正在执行的线程,而将调用join()的线程加入进来直至其执行完毕才恢复原线程
mt.join();
}
System.out.println(Thread.currentThread().getName()+": "+i);
}
}
}
class MyThread extends Thread{
@SuppressWarnings("static-access")
@Override
public void run() {
for(int i = 0;i<100;i++){
try {
//显式的使线程睡眠1秒再继续执行
Thread.currentThread().sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+": "+i);
}
}
}
2、继承Runnable接口实现多线程
package com.kexin.study;
/**
* 通过接口实现多线程经常用来处理多个线程共享数据的情况
* @author KeXin
*
*/
public class TestThread2 {
public static void main(String[] args) {
//只需要new一个对象即可实现三个线程操作同一个ticket
MyThread2 mythread = new MyThread2();
Thread thread1 = new Thread(mythread);
Thread thread2 = new Thread(mythread);
Thread thread3 = new Thread(mythread);
thread1.setName("thread1");
thread2.setName("thread2");
thread3.setName("thread3");
thread1.start();
thread2.start();
thread3.start();
}
}
class MyThread2 implements Runnable{
int ticket = 100;
@Override
public void run() {
while(true){
if(ticket>0)
System.out.println("线程"+Thread.currentThread().getName()+"处理ticket"+ticket--);
else
break;
}
}
}
使用继承Thread类实现同样的效果,进行对比一下:
package com.kexin.study;
public class TestThread {
public static void main(String[] args) {
//需要new三个对象
MyThread1 test1 = new MyThread1();
MyThread1 test2 = new MyThread1();
MyThread1 test3 = new MyThread1();
test1.setName("test1");
test2.setName("test2");
test3.setName("test3");
test1.start();
test2.start();
test3.start();
}
}
class MyThread1 extends Thread{
static int ticket = 100;
@Override
public void run() {
while(true){
if(ticket>0)
System.out.println("线程"+Thread.currentThread().getName()+"处理ticket"+ticket--);
else
break;
}
}
}
但是上面的例子里面存在着数据不同步的安全问题,具体解决方案请看下一节,感觉好像说评书哦