多线程处理相关
来源:互联网 发布:销售数据分析报告ppt 编辑:程序博客网 时间:2024/06/05 15:45
程序:计算机指令的集合;
进程:一个程序在其自身地址空间中的一次执行活动,是资源申请调度的单位;
线程:进程中一个单一的连续控制流程。一个进程可以拥有多个线程。但线程没有独立的存储空间,而是和该进程中的其他线程共享一个存储空间。
注:(1)单CPU的情况下,某个时刻只能出现一个线程。
之所以出现一个时刻可以看到很多线程,是因为由操作系统给所有线程划分时
间片,不断在之间切换。这个时间片很短,所以好像同一时间出现多个线程;
(2)多CPU的平台下,可以实现多线程的并发运行;
(3)多线程之间切换时,只需改变执行路线和局部变量即可。切换效率高。无需像
进程一样交换地址;
Java对多线程的支持
线程是在系统层实现,但Java在语言级就实现了。需要使用提供的特定接口。
两种方式:(1)从Thread类继承 (2)实现Runnable接口
第一种方式的代码:
Class MultiThread
{
publicstatic void main(String[] args)
{
MyThreadmythread = new MyThread();
mythread.start();//新线程启用
system.out.println("Current name is"+Thread.currentThread.getName());
}
}
Class MyThread extends Thread
{
publicvoid run()//线程的入口,必须有。里面放置需要实现的代码
{
system.out.println("Thisis thread is "+currentThread.getName());
}
}
运行结果:先打印main,后打印mythread。
分析:虽然启用了新线程,但主线程的时间片仍未到期。所以主线程继续向下运行,打印,待到线程结束后运行新线程中的内容。
1、 设置后台线程
myThread.setDaemon(true);
注:当系统中只剩后台线程时,自动退出。
2、暂停当前线程,调用其他线程
yield();
3、线程的优先级
设置优先级:setPriority(MAX/MIN/NORM_PRIORITY);
(Thread类里的最大/最小/缺省)
事实上,这三个参数分别代表着整数10、1、5,也就是说1-5的整数值都可以作为参数使用;
获得优先级:getPriority()
注意:java支持的是抢占性调度模型,同一时间点有多个线程处于可运行但未运行状态,即等待状态。只有一个线程处于运行状态。此线程终止运行有两种情况:1、自然终止,运行完毕
2、有比起优先级高的线程处于等待状态,此时会被抢占
4、第二种方式:实现Runnable接口
一个类,如果想要它的实例被一个线程运行,就必须在这个类中实现Runnable
接口,在其中定义一个不带参数的run()方法【这个接口只有这一个方法】事实上,之所以可以用继承Thread的方式来创建实现某功能的线程,也是因为Thread实现了Runnable接口。
第二种方式的代码:
Class MultiThread
{
publicstatic void main(String[] args)
{
MyThread mythread = new MyThread();
//以实现了接口的实例做参数,建立一个新线程,并start();
newThread(mythread).start();
system.out.println(Thread.currentThread.getName());
}
}
Class MyThread implements Runnable
{
publicvoid run()//线程的入口,必须有。里面放置需要实现的代码
{
system.out.println(Thread.currentThread.getName());
}
}
这两种方式有什么不一样
一般情况下推荐使用Runnable接口实现的方式建立新线程。
多个线程访问同一种资源的时候比较方便。
如以下代码:
代码:
Class MultiThread
{
publicstatic void main(String[] args)
{
MyThread mythread = new MyThread();
//以实现了接口的实例做参数,建立一个新线程,并start();
newThread(mythread).start();
new Thread(mythread).start();
new Thread(mythread).start();
system.out.println(Thread.currentThread.getName());
}
}
Class MyThread implements Runnable
{
intindex=0;
publicvoid run()//线程的入口,必须有。里面放置需要实现的代码
{
system.println(Thread.currentThread.getName()+index++);
}
}
说明:虽然建立了3个新的线程,但由于传进去的都是mythread实例,其访问的是同一个index,故打印出来的index的数字是递增的。这样可以保证某些参数被多个线程共享,从而达到变化的连续性。
补充:这个优点是可以通过匿名内部类实现的。以后要特别注意运用来实现需要的功能。
代码:
Class MultiThread
{
publicstatic void main(String[] args)
{
MyThreadmythread = new MyThread();
//下面开三个线程依旧共用一个实例
mythread.getThread().start();
mythread.getThread().start();
mythread.getThread().start();
system.out.println("Currentthread's name is "+Thread.currentThread.getName());
}
}
Class MyThread
{
intindex=0;
private Class innerThread extends Thread
{
publicvoid run()
{
system.out.println("Thisis thread is "+Thread.currentThread.getName()+index++);
}
}
//把上面的内部类定义为私有了,通过一个get方法返回需要的线程类
Thread getThread()
{
return innerThread;
}
}
利用多线程简单搭建火车票售票系统
代码
Class MultiThread
{
public static void main(String[]args)
{
MyThread mythread = newMyThread();
//新建4个线程
for(i=0;i<=3;i++)
{
newThread(mythread).start();
}
}
}
Class MyThreadimplements Runnable
{
int ticketNum=100;
public void run()
{
while(true)
{
if(ticketNum>0)
{
system.out.println("thread"+Thread.currentThread().getName()+"selltickes"+ticketNum);\
ticketNum--;
}
}
}
}
存在潜在的问题:时间片的结束、交替跳过了判断语句,导致余票为负,且一直往下错误的运行。这种情况在系统长时间运行过程中是有可能出现的,但短时间出现概率低。若需要观察,可以使用Thread.sleep(1000)来使得一个线程休眠,从而让错误出现。
由此引入下面的解决方案。
线程的同步
1、可能出现线程交替而发生异常的区域成为临界区
2、同步的两种方式:同步块,同步方法
3、同步块
原理:放置一个监听器(object),并给该监听器加锁。如果有线程已经在运行锁里面的代码,其他线程只能等待。待运行完,才能进入第二个线程,并重新加锁。
代码:
Class MyThread implements Runnable
{
int ticketNum=100;
Object object = new Object()
publicvoid run()
{
while(true)
{
synchronized(object)
{
if(ticketNum>0)
{
try
{
Thread.sleep(1000);
}
catch(Exceptione)
{
e.printStackTrace();
}
system.out.println("thread"+Thread.currentThread().getName()+"selltickes"+ticketNum);\
ticketNum--;
}
}
}
}
}
4、同步方法:
原理:在方法前面加关键字,调用时候即是同步的。实质是给该类的this加锁。
代码:public syncronized void sell()。
5、另:main也是一个线程,当这个线程的时间片没有结束时,在main里面所建立的线程建立了,但实际上是没有被运行的。待到main结束后,才能运行。
6、静态方法只属于类本身,不属于某个对象。对其调用也是直接从类中调用。
每个类也有一个锁,是对应的Class对象的锁。
7、线程的死锁
1、线程1进入并锁住了对象A的监视器;
2、线程2进入并锁住了对象B的监视器;
3、对象B在对象A中,线程1进不去对象B,等待;
4、对象A也在对象B中,线程2进不去对象A,等待。
造成死锁。
8、wait, notify, notifyAll
每个对象除了有一个锁外,还有一个等待队列(wait set)。应当在当前线程锁住对象时,去调用该对象的wait方法。当调用其notify方法时,会从其等待队列中任意删除一个线程,使其成为可运行的;当调用其notifyAll方法时,会清空其等待队列,使其均可以运行。
- 多线程处理相关
- Android多线程相关处理及用法
- Unity如何使用多线程处理 UnityEngine相关的内容
- 多线程相关
- 多线程相关
- 多线程相关
- 多线程相关
- 多线程 相关
- 多线程相关
- 多线程相关
- 多线程相关
- 多线程相关
- 多线程相关
- 多线程相关
- 多线程相关
- 多线程处理
- 多线程处理
- 多线程处理
- linux shmget
- angularjs+jquery 实现html国际化
- ubuntu引导新内核
- Hustler, Designer, Hacker,黄金三角组成完美创业团队
- 面向对象的设计原则,接口和抽象类区别
- 多线程处理相关
- Mysql的Locked状态
- 伤感的restart ear nullpointexception in weblogic
- 一个男人为他媳妇写的,看了特感动!
- IIS问题汇总
- volatile 与 cache 的疑惑
- Debug和Release版本--打印log
- javac在cmd中运行javac 不是内部或外部命令
- 【求助】Eclipse和go怎么没有自动联想