您的位置:首页 > 其它

多线程

2015-07-21 15:18 344 查看
1、进程、线程概念

进程:一个正在执行中的程序。每一个进程执行都有一个执行顺序。该顺序是一个执行路径,或者叫一个控制单元。

线程:就是进程中的一个独立的控制单元。线程在控制着进程的执行。

注:一个进程中至少有一个线程。

【 J VM 启动时(通过命令行参数java启动)会有一个java.exe进程。该进程中至少有一个线程负责java程序的执行。而且这个线程运行的代码存在于main方法中。该线程称之为主线程。扩展:更加细节的说明jvm,其实jvm启动不止一个线程,还有负责垃圾回收机制的线程。】

2、创建线程方式有两种

第一种方式:继承Thread类。

步骤:

1,定义类继承Thread。

2,复写Thread类中的run方法。

目的:将自定义代码存储在run方法中,让线程通过start方法启动后来运行。

3,调用线程的start方法,

该方法两个作用:启动线程,调用run方法。

线程创建:

public class MultiThread {

public static void main(String[] args) {
//创建并启动线程一
//new Demo().start();

//创建并启动线程二
new Thread(new Demo2()).start();

//主线程执行程序
for(int i=0; i<1000; i++) {
System.out.println(Thread.currentThread().getName() + ": The world " + i);
}
}
}
//定义线程的第一种方法:继承自Thread类
class Demo extends Thread {
public void run() { //封装要运行的代码
for(int i=0; i<1000; i++) {
System.out.println(Thread.currentThread().getName() + ": Hello java " + i);
}
}
}
//定义线程的第二种方法:实现Runnable接口
class Demo2 implements Runnable {
public void run() { //封装要运行的代码
for(int i=0; i<1000; i++) {
System.out.println(Thread.currentThread().getName() + ": Hello java " + i);
}
}
}
实现方式和继承方式的区别?

1、继承Thread,线程运行代码存放在Thread子类run方法中

实现Runnable,线程运行代码存放在Runnable接口子类run方法中

2、实现方式避免了java单继承的局限性。

在定义线程类时,建议使用实现方式

多窗口卖票示例:

public class SaleTicket {

public static void main(String[] args) {
Ticket t = new Ticket();
new Thread(t).start();
new Thread(t).start();
new Thread(t).start();
new Thread(t).start();
}

}

class Ticket implements Runnable {
private int ticket = 100;
public void run() {
while(ticket > 0) {
System.out.println(Thread.currentThread().getName() + "sale : " + ticket--);
}
}
}


(若继承Thread,则Ticket的ticket属性应为static)
多线程安全问题

问题出现的状况:

当多个线程在操作同一个共享数据时,一个线程的多条语句中只执行了一部分,CPU执行权即分配到了其它的线程中执行。导致共享数据错误。

解决办法:

单个线程在操作共享数据时,其它线程不能参与进来。

java用的1、同步代码块来实现安全:

synchronized(对象) {

需要被同步的语句;

}

对象如同锁,没有锁的线程就算取得了CPU的执行权也不能执行。

线程加锁带来的弊端:要有锁对象,所以耗资源;要判断锁,所以效率稍减。

2、同步函数

public synchronized void method(Type args) {

需要被同步的语句;

}

同步非静态函数用的锁是this。如果同步静态函数:所用的锁不是this,因为静态方法中不能出现this。用的是 类名.class是Class类型对象。 如果一个程序中有安全问题,使用同步时应注意:

1、明确多线程运行代码(一般为run方法里调用的语句,以及其附带语句(调用了其它的方法))有哪些 2、明确共享数据为何 3、明确运行代码中有哪些语句操作共享数据

使用同步还会出安全问题:此时定为同步的两个前提条件中的一个不满足所造成:1、必须有两个或两个以上的线程 2、必须是多个线程使用同一把锁。

多线程通信:

<span style="color:#666666;">public class ThreadCommunication{

public static void main(String[] args) {
Res r = new Res();
new Thread(new Input(r)).start();
new Thread(new Output(r)).start();
}

}
//共享资源
class Res {
private String name;
private String sex;
private boolean flag = false;
//设置方法
public synchronized void set(String name, String sex){
if(flag)//flag=true表示设置过的还未打印,有数据则等待
try{this.wait();}catch(InterruptedException e){e.printStackTrace();}
this.name = name;
this.sex = sex;
flag = true;
this.notify();
}
//打印方法
public synchronized void out(){
if(!flag)
try{this.wait();}catch(InterruptedException e){e.printStackTrace();}
System.out.println(name + ".........." + sex);
flag = false;
this.notify();
}
}
//输入线程
class Input implements Runnable{
private Res r;
Input(Res r) {
this.r = r;
}
public void run() {
int x = 0;
while(true) {
if(x==0) {
r.set("lisi", "man");
}
else {
r.set("丽丽", "女女女女");
}
x = (x+1)%2;//控制x在0和1之间不断交替,从而让设置的内容不同。
}
}
}
//输出线程
class Output implements Runnable{
private Res r;
Output(Res r) {
this.r = r;
}
public void run() {
while(true) {
r.out();
}
}
}  </span>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: