------- android培训、java培训、期待与您交流! ----------
回顾知识:Thread类、模版方法设计模式、匿名内部类实现Runnable开启线程,线程的同步互斥、线程间通信、线程池
计算机中正在执行的程序叫做进程,而线程是进程中某个单一顺序的控制流。多线程是指单个程序中可以同时运行多个不同的线程,执行不同的任务。
线程状态图:
Thread类与模版方法设计模式
首先,启动线程是用start()方法。但线程运行的代码块存在run()方法中。这里Thread类用到了模版方法设计模式。
模版方法设计模式是指:通过把不变的的行为搬移到超类,去除子类中重复的代码来体现它的优势;当不变的和可变的行为在子类实现中混合在一起的时候,不变的行为就会在子类中重复实现,通过模板方法模式把这些行为搬移到单一的地方,这样就可以帮助子类摆脱重复不变行为的纠缠。
线程的同步互斥与线程间的通讯
开启多线程后带来的安全问题:当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,
还没有执行完,另一个线程参与进来执行。导致共享数据的错误。解决办法是:对多条操作共享数据的语句,
只能让一个线程都执行完。在执行过程中,其他线程不可以参与执行。
在java中,用同步代码块就可以解决这个问题。
同步代码块的格式:synchronized(对象){
需要被同步的代码;
}
同步的好处和弊端。
同步的好处:解决了线程的安全问题。
同步的弊端:相对降低了程序的效率,因为同步外的线程都会判断同步锁。
同步的前提:
同步中必须有多个线程,并使用同一个锁。
同步函数的锁是this.
同步函数和同步代码块的区别:
同步函数的锁是固定的this。
同步代码块的锁是任意的对象。
静态的同步函数使用的锁是:该函数所属的字节码文件对象。
可以用getClass获取,也可以用 当前类名.class表示。
线程间的通讯:其实就是多个线程在操作同一个资源,但是操作的动作不同。如下代码
体现了java中的等待唤醒机制。
class Producer implements Runnable
{
private Resource res;
Producer(Resource res)
{
this.res = res;
}
@Override public void run()
{
// TODO Auto-generated method stub
while(true)
{
res.set("lisi");
}
}
}
class Consumer implements Runnable
{
private Resource res;
Consumer(Resource res)
{
this.res = res;
}
@Override public void run()
{
// TODO Auto-generated method stub
while(true)
{
res.out();
}
}
}
class Resource
{
private String name;
private int count = 1;
private boolean flag = false;
public synchronized void set(String name)
{
while(flag)
{
try
{
this.wait();
}
catch (Exception e)
{
// TODO: handle exception
}
}
this.name = name+"--"+count++;
System.out.println(Thread.currentThread().getName()+"...生产者.."+this.name);
flag = true;
this.notifyAll();
}
public synchronized void out()
{
while(!flag)
{
try
{
this.wait();
}
catch (Exception e)
{
// TODO: handle exception
}
}
System.out.println(Thread.currentThread().getName()+"...消费者........."+this.name);
flag = false;
this.notifyAll();
}
}
public class ThreadPoolTest
{
/**
* @param args
*/
public static void main(String[] args)
{
Resource res = new Resource();
new Thread(new Producer(res)).start();
}
}
死锁以及简单的死锁示例
死锁产生的原因是同步中嵌套同步,但锁却不同。
class Test implements Runnable
{
private boolean flag;
Test(boolean flag)
{
this.flag = flag;
}
public void run()
{
if(flag)
{
while(true)
{
synchronized(MyLock.locka)
{
System.out.println(Thread.currentThread().getName()+"...if locka ");
synchronized(MyLock.lockb)
{
System.out.println(Thread.currentThread().getName()+"..if lockb");
}
}
}
}
else
{
while(true)
{
synchronized(MyLock.lockb)
{
System.out.println(Thread.currentThread().getName()+"..else lockb");
synchronized(MyLock.locka)
{
System.out.println(Thread.currentThread().getName()+".....else locka");
}
}
}
}
}
}
class MyLock
{
static Object locka = new Object();
static Object lockb = new Object();
}
class DeadLockTest
{
public static void main(String[] args)
{
Thread t1 = new Thread(new Test(true));
Thread t2 = new Thread(new Test(false));
t1.start();
t2.start();
}
}
线程池