多线程
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方法。
线程创建:
1、继承Thread,线程运行代码存放在Thread子类run方法中
实现Runnable,线程运行代码存放在Runnable接口子类run方法中
2、实现方式避免了java单继承的局限性。
在定义线程类时,建议使用实现方式
多窗口卖票示例:
(若继承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、必须是多个线程使用同一把锁。
多线程通信:
进程:一个正在执行中的程序。每一个进程执行都有一个执行顺序。该顺序是一个执行路径,或者叫一个控制单元。
线程:就是进程中的一个独立的控制单元。线程在控制着进程的执行。
注:一个进程中至少有一个线程。
【 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>
相关文章推荐
- 永远不要测试某个特定的浮点数值
- python通过http请求发送soap报文进行webservice接口调用
- jquery.validate详解一
- 自定义BaseActivity
- 该blog为“打勾勾”应用的技术支持博客
- JavaScript 哪些值可以作为If 判断条件
- HighChart学习-更新数据data Series与重绘
- eclipse修改tomcat的编码
- redis2.6.4 在centos6.4上的安装
- Java获取http和https协议返回的json数据
- Oracle触发器
- 内核模块 module_param()传递参数
- HDU2046骨牌铺方格
- C#将数据导入到excel中 出现 “object”未包含“get_Range”的定义
- tar命令的实用详解(C参数和排除文件 --exclude)
- Java中创建对象的四种方式
- C语言读写配置文件的方法
- 齐次线性方程组、齐次方程、齐次多项式
- [LeetCode]Longest Common Prefix
- 比isConnected()更靠谱的的获取socket实时连接状态!