您的位置:首页 > 其它

多线程(线程的概述,创建线程,控制线程,线程同步,线程池)

2015-07-23 06:43 836 查看
1.线程的概述

线程是:当一个程序运行时,内部可能包含了多个顺序的执行流,每个执行流就是一个线程。

线程与进程的区别:进程有独立的内存空间地址,线程共享内存空间地址

进程是静态的指令集,线程是动态的指令集

进程并行性,线程并发性

2.创建线程

方法一:继承Thread类来创建线程类

示例:

/**
* 继承Thread,重写run()方法
*
* @author Administrator
*
*/
public class Demo01 extends Thread {
public static void main(String[] args) {
Demo01 d1 = new Demo01();
d1.start();
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + "--" + i);
}

}

@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + "--" + i);
}
}

}


运行结果:



方法二:实现Runnable接口创建线程类

示例:

/**
* 继承Runnable接口,重写 run()方法
* @author Administrator
*
*/
public class Demo02 implements Runnable {

public static void main(String[] args) {
Demo02 d = new Demo02();
new Thread(d).start();//作为参数传给Thread对象
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + "--" + i);

}

}

public void run() {

for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + "--" + i);

}

}

}


运行结果:



两者比较:

继承接口Runnable虽然比较麻烦,但是接口可以多继承,还可以继承其他的类,在实际运用中更多。

3.线程的生命周期

线程有新建,就绪,运行阻塞和死亡状态。具体关系如图所示



4.控制线程

1)join线程

让一个线程等待另外一个线程完成。

示例:

public class Demo03 {
public static void main(String[] args) {
Thread a = new Thread(new A());
Thread b = new Thread(new B());
a.start();
b.start();
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + "--" + i);
if(i == 3){
try {
//主线程等待a,b线程执行完才执行
a.join();
b.join();
} catch (InterruptedException e) {
e.printStackTrace();
}

}

}

}

}

class A implements Runnable{

public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + "--" + i);

}
}
}

class B implements Runnable{

public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + "--" + i);

}

}

}


运行结果:



2)后台线程

后台线程是为其他线程服务的,其他线程停止后他也将停止。JVM中的垃圾回收线程是典型

的后台线程。

示例:

public class Demo03 {
public static void main(String[] args) {
Thread a = new Thread(new A());
Thread b = new Thread(new B());
a.start();
b.setDaemon(true);//把b线程设为守护线程
b.start();
}

}

class A implements Runnable{

public void run() {
for (int i = 0; i < 1; i++) {
System.out.println(Thread.currentThread().getName() + "--" + i);

}
}
}

class B implements Runnable{

public void run() {
while(true){
System.out.println("我是B,守护线程!");
}
}

}


运行结果:



3)线程休眠:sleep

让正在执行的的线程sleep一下,线程会发生阻塞,线程唤醒时则继续执行。

示例:

public class Demo03 {
public static void main(String[] args) {
Thread a = new Thread(new A());
a.start();
for (int i = 0; i < 3; i++) {

System.out.println(Thread.currentThread().getName() + "--" + i);

}
}

}

class A implements Runnable {

public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + "--" + i);
try {
Thread.sleep(1000);//让线程睡眠1秒
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}


运行结果:



4)线程让步:yield

让线程等待一下,并不会使线程发生阻塞,而是直接让线程进入就绪状态,让系统重新调度一下,也是完全有可能系统又重新调度了本线程。

示例:

public class Demo03 {
public static void main(String[] args) {
Thread a = new Thread(new A());
a.start();
for (int i = 0; i < 3; i++) {
a.yield();//每执行一次主线程,让a线程等待一次
System.out.println(Thread.currentThread().getName() + "--" + i);

}
}

}

class A implements Runnable {

public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + "--" + i);

}
}
}


运行结果:



5)改变线程的优先级

改变线程的优先级,优先级高的线程会得到更多的执行机会,但不绝对。

示例:

public class Demo03 {
public static void main(String[] args) {
Thread a = new Thread(new A());
a.setPriority(10);//把a的优先级设成最高,得到更多的调度机会
a.start();
for (int i = 0; i < 3; i++) {
System.out.println(Thread.currentThread().getName() + "--" + i);

}
}

}

class A implements Runnable {

public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + "--" + i);

}
}
}


运行结果:



5.线程同步

1)同步代码块

示例:

public class Demo03 {
public static void main(String[] args) {
A a = new A();
Thread t1 = new Thread(a);
Thread t2 = new Thread(a);
t1.start();
t2.start();
for (int i = 0; i < 3; i++) {
System.out.println(Thread.currentThread().getName() + "--" + i);

}
}

}

class A implements Runnable {
Object obj = 1;
int a = 0;

public void run() {
synchronized (obj) { // 使用synchronized同步代码块
for (int i = 0; i < 5; i++) {
a++;
System.out.println(Thread.currentThread().getName() + "--" + i
+ "--" + a);

}
}

}
}


运行结果:



2)同步方法

相当于同步代码块中,同步的对象为this,也就是说任意时刻只能有一个线程进入该对象中进行操作。

示例:

public class Demo03 {
public static void main(String[] args) {
A a = new A();
Thread t1 = new Thread(a);
Thread t2 = new Thread(a);
t1.start();
t2.start();

}

}

class A implements Runnable {
Object obj = 1;
int a = 0;
int b = 0;

public void run() {
math1();
math2();
}
// 使用synchronized方法
public synchronized void math1(){
a++;
System.out.println(Thread.currentThread().getName() +"我是a++" + a);
}
// 使用synchronized方法
public synchronized void math2(){
b--;
System.out.println(Thread.currentThread().getName() +"我是b--" + b);
}
}


运行结果:



3)同步锁

示例:

public class Demo03 {
public static void main(String[] args) {
A a = new A();
Thread t1 = new Thread(a);
Thread t2 = new Thread(a);
t1.start();
t2.start();

}

}

class A implements Runnable {
Object obj = 1;
int a = 0;
int b = 0;

//定义锁对象
private final ReentrantLock lock = new ReentrantLock();

public void run() {
math1();
}

public  void math1(){
lock.lock();//加锁
for (int i = 0; i <5; i++) {
a++;
System.out.println(Thread.currentThread().getName() +"我是a++" + a + "--" + i);
}

lock.unlock();//释放锁
}

}


运行结果:



4)死锁

当两个线程互相等待对方释放同步监视器的时候很容易发生死锁。

示例:

public class Demo05 implements Runnable {
C c = new C();
B b = new B();

public void init(){
c.cMathb(b);
}
public static void main(String[] args) {
//主线程放在第一通常不会死锁,因为主线程的优先级比较高
Demo05 d = new Demo05();
new Thread(d).start();
for(int i = 0; i < 100; i++){
d.init();
}

}

public void run() {
for(int i = 0; i < 100; i++){
b.bMathc(c);
}
}

}

class C {
public synchronized void cMathb(B b) {
b.math();
System.out.println(Thread.currentThread().getName() + "--"+ "c中的cMathb()方法");
}

public synchronized void math() {
System.out.println("c中的math方法");
}

}

class B {
public synchronized void bMathc(C c) {
c.math();
System.out.println(Thread.currentThread().getName() + " --"+ "c中的cMathb()方法");

}

public synchronized void math() {
System.out.println("b中的math()方法");
}
}


运行结果:



6.线程池

Java5新增了Executor工厂类来实现生产线程池,开发者不需要手动实现自己的线程池。

示例:

public class Demo06 {

/**
* @param args
*/
public static void main(String[] args) {
ExecutorService pool = Executors.newFixedThreadPool(3);
Runnable r =new Runnable() {
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + "--" + i);
}
}
};

pool.submit(r);
pool.submit(r);
pool.submit(r);
//关闭线程池
pool.shutdown();
}

}


运行结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: