Java学习笔记(十二)
线程
程序是为完成特定任务、用某种语言编写的一组指令的集合。是一段静态的代码。
进程是程序的一次执行过程,是一个动态的概念。
什么时候需要使用多线程
- 程序需要同时执行两个或多个任务
- 程序需要实现一些需要等待的任务,如搜索、用户输入等
- 后台运行的程序
多线程的创建和启动
java.lang.Thread
每个线程都是调用Thread对象的run()方法来完成操作的,然后通过start()来调用这个线程,创建方式如下:
- 继承Thread对象
main{
Thread t0=new TestThread();
t0.start();
}
public class TestThread extends Thread{
@Override
public void run(){
//运行代码
}
}
- 实现Runnable接口
main{
Thread t3=new Thread(new TestRunnable());
Thread t4=new Thread(new TestRunnable(),"name");
t3.start();
}
public class TestRunnable implements Runnable{
@Override
public void run(){
//运行代码
System.out.println(Thread.currentThread().getName());
}
}
两种方式都需要最终通过Thread来运行run方法,但多个线程可以共享同一个接口实现类的对象,非常适合多个相同线程来处理同一份资源,因此一般通过继承方式实现线程较多(同时也可以避免单继承的局限性)。
Thread类的有关方法
- getName():默认名称是Thread-xx
- setName()
- 优先级(数字越大优先级越高,范围为1~10,默认为5)
–setPriority()
–getPriority() - static yield():线程让步,把执行机会让给优先级相同弄或者更高的线程
- join():直到join线程执行完毕才使调用join方法的线程开始执行
- sleep():指定睡眠毫秒数,会抛出InterruptedException
- stop(): 强制线程生命周期结束
- isAlive():是否还活着
线程的生命周期
Thread.State
线程的同步与死锁
- 普通方法加同步锁,锁的是调用当前方法的对象
- static方法加同步锁,锁的是所有对象
- synchronized,锁的是当前对象
main{
Account a=new Account();
User u_v=new User(a,2000);
User u_a=new User(a,2000);
Thread weixin=new Thread(u_v,"weixin");
Thread zhifubao=new Thread(u_a,"zhifubao");
weixin.start();
zhifubao.start();
}
class User implements Runnable{
int money;
public User(Account account,money){
this.account=account;
this.money=money;
}
Account account;
@Override
public void run()
{
account.drawiny(money);
}
}
class Account{
static int money=3000;
//在普通方法前加synchronized锁的是整个对象(static除外)
public synchronized void drawing(int m){
if(money < m){
return;
}
String name=Thread.currentThread().getName();
System.out.println(name+money);
money-=m;
System.out.println(money);
}
public void drawing(int m){
synchronized(this){
if(money < m){
return;
}
String name=Thread.currentThread().getName();
System.out.println(name+money);
money-=m;
System.out.println(money);
}
}
}
线程的通信
Java.lang.Object中提供的这三个方法只有在synchronized修饰的方法或代码块中才可以使用
- wait():挂起
- notify()/notifyAll():唤醒
public class Test3{
public static void main(String[] args){
Clerk c=new Clerk();
new Thread(new Runnable(){
@Override
public void run(){
synchronized(c){
while(true){
if(c.productNum == 0){
//生产
c.productNum++;
c.notify();
}else{
c.wait();
}
}
}
}
},"生产者").start();
}
}
Class Clerk{
public static int productNum=0;
}