线程是认证考试中考的最多的一部分
简单的说,就是一个程序它可以有好几个分身在电脑中执行。
1.进程与线程
进程:执行中的程序叫做进程,即当程序执行时的这个动态过程就是一个进程。
在电脑中同一个份程序可以执行好几个,就是说好几个工作相同的进程在电脑中执行。
线程:相同的代码产生好几个进程,有个问题就是一些东西重复浪费,一样的程序代码总有能够共用的代码、常量等。
threads就是使同一份程序产生好几个进程的效果,不同的threads之间能够达到某种程度的资源共享,threads是轻量级的进程。
2.Java中负责threads功能是类是:java.lang.Threads
实现方式有两种:一是继承;二是接口
1)继承——这种方式比较单一简单,因为java的类只能单一继承,继承了Threads类,就无法继承别的类了
2)接口——实现Runnable接口,符合面向对象设计精神,可以继承多个接口
继承:Hello1.java
public class Hello1 extends Threads
{
String name ;
public Hello1 (String n)
{
name = n ;
}
public void run()
{
for(int i = 1 ; i <= 10 ;i++)
{
System.out.println(name + "Hello" + i)
}
}
}
接口:Hello2.java
public class Hello2 implement Runnable
{
String name ;
public Hello2 (String n)
{
name = n ;
}
public void run()
{
for(int i = 1 ; i <= 10 ;i++)
{
System.out.println(name + "Hello" + i)
}
}
}
运行线程:
public class ThreadsExample
{
public static void main(String argv[])
{
Hello1 h1 = new Hello1("Threads1") ; 创建类对象实例
Threads t1 = new Threads(h1) ; 创建线程对象实例
t1.start() ; 运行线程
//Hello2的运行同上
//main本身也是一个Threads
}
}
停止线程:
public void run()
{
int i = 0 ;
while(!isStop)
{
i++ ;
System.out.println(name + "Hello" + i)
}
public void stop()
{
isStop = true ;
}
}
添加了一个isStop属性用于控制循环条件,一但停止了线程将无法恢复,只能重新产生另一个Threads对象
暂停Threads运行:
1)sleep
数字钟实例MyClock.java
public void run()
{
while(true)
{
try
{
Thread.sleep(1000);
time.setText(getTime) ;
}
catch
{
System.err.println(e);
}
}
}
Threads对象睡醒后,进程等待执行状态,而不是立刻执行状态
2)yield
让Threads对象立刻暂时停止执行,并且直接从执行状态转移到等待执行状态
3)join
当一个系统中有好几个Threads在执行,有时候某个Threads甲需要等待另外一个Threads乙完成某件事情后,甲才能继续执行下去,这时甲在乙还没有执行能够完成之前,就必须要做等待的工作
3.锁
多个线程之间共享一些资源对象,例如银行帐号在各账户之间转移账目,各账户数据就是共享资源对象;扑克游戏、棋子游戏中各个玩家对扑克棋子不断进行操作,这些扑克和棋子就是共享资源对象
Java中用关键字synchronized为共享资源加锁。用synchronized修饰一个对象时,在任何一个时刻只能有一个线程访问,即只能有一个线程能取得加锁对象的钥匙,对加锁对象进行操作,只有该线程操作完毕后,其他线程才能访问该对象,进行操作,从而达到对共享资源访问的保护。
给对象加锁的方式有2种:1是给方法加锁,2是给方法体中的某些对象加锁
1)
public synchronized 返回值类型 方法名(参数列表)
{
...;
//定义处理共享资源列表
}
2)
public 返回值类型 方法名(参数列表)
{
...;//定义对非共享资源的访问
synchronized(this) //定义对共享资源的访问
{
...; //被加锁的某些共享的对象或数据
}
}
锁的唤醒:线程同步和唤醒方法
wait()方法使线程一直等待下去
wait(1000)方法使线程等待1000毫秒后又成为就绪状态
notify()方法唤醒没有指定等待时间的线程
notifyAll()用户唤醒多个执行了wait()方法而等待的线程
方法wait()和sleep()和suspend()方法一样,都能使线程等待而停止执行,其区别在于sleep()方法和suspend()方法不会释放对象的锁,而wait()方法进入等待时,可是释放对象的锁
另外还有三种方式也会把锁释放:1是用break语句跳离锁定语句块,这对synchronized声明的方法无作用;2是遇到return语句;3是遇到异常
简单预防死锁的办法就是给每个锁加上优先级