在线程中启动启动其他线程
线程通过调用star()方法将启动该线程,使之从新建状态进入就绪队列排队。一旦轮到它享用CPU资源的时候,就可以脱离创建它的主线程,开始自己的生命周期。
线程一计算完1+2+…+50,线程二继续计算51+52+…+100。
package com.thread;
public class MultiThread_StartOtherThread {
public static void main(String[] args) {
Calculate cal = new Calculate();
Thread thread1 = new Thread(cal);
thread1.setName("1");
thread1.start();
}
}
class Calculate implements Runnable{
int i=1 , sum=0;//线程共享数据
public void run() {
Thread thread =Thread.currentThread();
while(i<=100){
sum = sum+i;
if(i==50){
System.out.println(thread.getName()+":"+sum);
Thread thread2 = new Thread(this);//thread2与thread1的目标对象相同
thread2.setName("2");
thread2.start();
i++;
return;//thread1死亡
}
i++;
try{
Thread.sleep(20);
}catch(InterruptedException e){}
}
System.out.println(thread.getName()+":"+sum);
}
}
线程的interrupt()方法
interrupt()方法的功能是中断线程。
若当前线程没有中断它自己或当前线程无法修改该线程,则该线程的checkAccess方法会被调用,这可能抛出SecurityException。
若线程在调用Object类的wait(),join(),sleep()方法中受阻,则其中断状态将被清除,收到一个InterruptException异常。
若该线程在可中断通道上的I/O操作中受阻,则该通道将被关闭,该线程的中断状态将被设置并且该线程收到一个ClosedByInterruException异常。
使用interrupt()中断线程方法,让一个线程唤醒另一个休眠线程。
package com.thread;
public class MultiThread_interrupt {
public static void main(String[] args) {
Room room = new Room();
room.student.start();
room.teacher.start();
}
}
class Room implements Runnable{
Thread student,teacher;
Room(){
student = new Thread(this);
teacher = new Thread(this);
student.setName("Student");
teacher.setName("Teacher");
}
public void run() {
if(Thread.currentThread()==student){
try{
System.out.println("Student is sleeping");
Thread.sleep(1000*60);
}catch(InterruptedException e){
System.out.println("wake up");
}
System.out.println("listen class");
}
else if(Thread.currentThread()==teacher){
System.out.println("teacher say begin class");
try{
Thread.sleep(200);
}catch(InterruptedException e){}
student.interrupt();//唤醒Student
}
}
}
线程的同步
一个Java程序的多线程间可以共享数据,就存在两个或多个线程同时使用相同且有限资源的可能性,这样就可能产生冲突。
多线程的同步,就是使多个访问同一个数据的线程,按序进行,以免数据出错。当一个线程处理某数据时,其他欲访问改数据的线程必须等待,直到前一线程处理改数据完毕。
Java采用synchronized关键词来实现同步。其原理是赋予该对象唯一的一把“钥匙”(也叫“同步锁”),当多个线程进入对象,只有取得对象钥匙的进程,才可以访问同步方法,其他线程必须等待,直到该线程用wait()方法放弃这把钥匙,并执行notifyAll()方法通知所有因使用这个同步方法而处于等待的线程,让它们结束等待。
notifyAll():中断的线程会从中断处继续执行这个同步方法,并遵循“先中断先执行”的原则。
模拟三人排队买票,张三,李四,王五。售票员只有三张10元的钱,票10元一张。张三拿着一张50元排第一,李四拿着一张20元排第二,王五拿着一张10元排最后。
package com.thread;
public class MultiThread_synchronized {
public static void main(String[] args) {
Queue queue = new Queue();
queue.zs.start();
queue.ls.start();
queue.ww.start();
}
}
class Queue implements Runnable{
Saler s;
Thread zs,ls,ww;
Queue(){
s=new Saler();
zs = new Thread(this);
ls = new Thread(this);
ww = new Thread(this);
}
public void run(){
if(Thread.currentThread()==zs){
s.charge(50);
}else if(Thread.currentThread()==ls){
s.charge(20);
}else if(Thread.currentThread()==ww){
s.charge(10);
}
}
}
class Saler{
int number10=3,number20=0,number50=0;
public synchronized void charge(int money){
if(money==10){
number10++;
System.out.println("收您10元");
}
else if(money==20){
while(number10<1){
try{
wait();
}catch(InterruptedException e){}
}
number10--;
number20++;
System.out.println("收您20,找零10");
}
else if(money==50){
while((10*number10+20*number20)<40){
try{
wait();
}catch(InterruptedException e){}
}
number50++;
if(number20>0){
number20--;
number10=number10-2;
}else{
number10=number10-4;
}
System.out.println("收您50,找零40");
}
notifyAll();
}
}