线程生命周期
new 新建状态
runnable 运行状态
blocked 阻塞状态、等待某个监视器的锁
waiting 冻结状态、无限等待某个监视器的锁
timed-waiting 等待状态、由另一个线程决定等待的时间
terminated 退出状态
线程控制
让run()结束,控制循环让run方法结束
join()
调用join方法的线程对象强制运行,该线程强制运行期间,其他线程无法运行.但是在调用join()方法之前开起的方法可以运行。
import java.util.*;
class ThreadTest implements Runnable
{
public void run()
{
for(int i=0;i<100;i++)
System.out.println(Thread.currentThread().getName()+"running");
}
}
class ThreadDemo
{
public static void main(String[] args)
{
ThreadTest t=new ThreadTest();
Thread t1=new Thread(t,"b");
new Thread(t,"a").start(); //要先start(),因为join()不会调用run方法,它只是强制让该线程执行完才会执行下面的线程。但是在join之前的执行的线程照常执行。
t1.start();
try
{
t1.join(); //会抛出InterruptedException
}
catch(InterruptedException e)
{
e.printStackTrace();
}
new Thread(t,"c").start();
}
}
多线程安全
当多个线线程同时操作一个类的数据,其结果与单个线程操作的结果一样,说明是同步的、安全的。
不安全的线程
class ThreadTest implements Runnable
{
private int tickts=100;
public void run()
{
for(;tickts>0;)
{
try
{
Thread.sleep(10);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" sale No."+tickts--);
}
}
}
class ThreadDemo
{
public static void main(String[] args)
{
ThreadTest tt=new ThreadTest();
new Thread(tt,"A").start();
new Thread(tt,"B").start();
new Thread(tt,"C").start();
}
}
会出现一张票卖两次的情况。
因为当C线程执行到sleep之后丧失了CPU执行权,这时A线程获得执行权将代码执行到了System。然后C又获得了执行权,此时tickts为0的值以被A线程先执行了。
同步代码
class ThreadTest implements Runnable
{
private int tickts=100;
public void run()
{
for(;tickts>0;)
{
synchronized(this) //当一个线程执行到这时,就像关了门一样,只要先进去的线程不出来,后面的线程就不能执行该代码块中的内容
{
try
{
Thread.sleep(10);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" sale No."+tickts--);
}
}
}
}
class ThreadDemo
{
public static void main(String[] args)
{
ThreadTest tt=new ThreadTest();
new Thread(tt,"A").start();
new Thread(tt,"B").start();
new Thread(tt,"C").start();
}
}
线程通信
让A线程执行一段代码,紧接B线程执行一代码,轮回执行。
import java.util.concurrent.locks.*;
import java.util.*;
class Person
{
private String name;
private String sex;
ReentrantLock lock=new ReentrantLock();
Condition jin=lock.newCondition();
Condition chu=lock.newCondition();
private int flag=0; //定义一个标记
public void set(String name,String sex)
{
lock.lock(); //锁
try
{
if(flag==1) //如果有值flag为1,为1就不胜存值了,等待输出
{
try
{
jin.await(); //设置线程等待
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
this.name=name;
this.sex=sex;
System.out.println("Setting...........");
flag=1; //存完值后将标记设为1
chu.signal(); //唤醒输出线程
}
finally
{
lock.unlock();
}
}
public void get()
{
lock.lock();
try
{
if(flag==0) //if flag is 0,the thread of printing wont print.waiting for setting.
{
try
{
chu.await(); //thread of print is waiting.
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
System.out.println(this.name+"....."+this.sex);
flag=0; //输出后将标记设为0
jin.signal(); //唤醒设置线程
}
finally
{
lock.unlock();
}
}
}
class in implements Runnable
{
private Person p;
in(Person p)
{
this.p=p;
}
public void run()
{
for(int i=0;i<100;i++)
{
if(i%2==0)
p.set("ZhangSan","man");
else
p.set("WangLi","woman");
}
}
}
class out implements Runnable
{
private Person p;
out(Person p)
{
this.p=p;
}
public void run()
{
for(int i=0;i<100;i++)
{
p.get();
}
}
}
class ThreadDemo
{
public static void main(String[] args)
{
Person p=new Person();
new Thread(new in(p)).start();
new Thread(new out(p)).start();
}
}