关于线程的总结
有两种方式:
1.是继承Thread类
2.是实现Runnable接口
一般用后者,java单继承,这样可以使这个类继承别的类。他们都要重写run方法
下面是一个死锁的java小程序
public class DieLock {
public static void main(String[] args) {
Thread t1=new Thread(new Test(true));
t1.start();
Thread t2=new Thread(new Test(false));
t2.start();
}
}
class Lock {
static Object lock1 = new Object();
static Object lock2 = new Object();
}
class Test implements Runnable {
boolean b;
Test(boolean b) {
this.b = b;
}
@Override
public void run() {
if (b) {
synchronized (Lock.lock1) {
System.out.println("if lock1");
synchronized (Lock.lock2) {
System.out.println("if lock2");
}
}
} else {
synchronized (Lock.lock2) {
System.out.println("else lock2");
synchronized (Lock.lock1) {
System.out.println("else lock1");
}
}
}
}
}
主线程中启动了两个线程执行run方法,
第一个run方法进入if中去,打印了if lock1,开始调用lock2,
第二个run方法进入else中去,打印了else lock2,开始调用lock1
由于在if的同步代码块中lock1要调用lock2,而在else同步代码块
中lock2要调用lock1,这样他们都要相互调用,但是有调用不到就产生死锁了
唤醒等待机制代码
启动两个线程,一个写入,一个打印出来,并且保证写入之后就打印出来而不是
写入。
class Res {
private String name;
private String sex;
private boolean flag = false;
public synchronized void set(String name,String sex)
{
if(flag)
try {this.wait();} catch (Exception e) {}
this.name=name;
this.sex=sex;
flag=true;
this.notify();
}
public synchronized void out()
{
if(!flag)
try {this.wait();} catch (Exception e) {}
System.out.println(name+"....."+sex);
flag=false;
this.notify();
}
}
class Intput implements Runnable {
private Res r;
int x = 0;
Intput(Res r) {
this.r = r;
}
public void run() {
while (true) {
if (x == 0) {
r.set("maik","man");
} else {
r.set("莉莉","女");
}
x = (x + 1) % 2;
}
}
}
class Output implements Runnable {
private Res r;
Output(Res r) {
this.r = r;
}
public void run() {
while (true) {
r.out();
}
}
}
class InputOutputDemo {
public static void main(String[] args) {
Res r = new Res();
Intput in = new Intput(r);
Output out = new Output(r);
Thread t1 = new Thread(in);
Thread t2 = new Thread(out);
t1.start();
t2.start();
}
}
等待唤醒的实例应用,生产消费,生产一个消费后,在生产,可以多个线程生产,多个线程消费
/*
商品生产(生产一个消费一个,显示的锁机制。显示的等待唤醒机制)
JDK5.0中提供了多线程升级解决方案。
将同步Synchronized替换成现实Lock操作。
将Object中的wait,notify,notifyAll。替换成Condition对象。
改对象可以通过Lock锁进行获取。
该示例中实现了本方只唤醒对方操作。
*/
import java.util.concurrent.locks.*;
class ProducerConsumerDemo2
{
public static void main(String[] args)
{
Resource res=new Resource();
Producer p=new Producer(res);
Consumer c=new Consumer(res);
Thread t1=new Thread(p);
t1.start();
Thread t2=new Thread(c);
t2.start();
Thread t3=new Thread(p);
t3.start();
Thread t4=new Thread(c);
t4.start();
}
}
class Resource
{
private String name;
private int count=1;
private boolean flag=false;
private Lock lock=new ReentrantLock();
private Condition condition_pro=lock.newCondition();
private Condition condition_con=lock.newCondition();
public void set(String name)
{
lock.lock();
try
{
while(flag)
condition_pro.await();
this.name=name+"---"+count++;
System.out.println(Thread.currentThread().getName()+"..生产者.."+this.name);
flag=true;
condition_con.signal();
}
catch (Exception e)
{
}finally{
lock.unlock();//释放锁的动作一定要执行。
}
}
public void out()
{
lock.lock();
try
{
while(!flag)
condition_con.await();
System.out.println(Thread.currentThread().getName()+"......消费者..."+this.name);
flag=false;
condition_pro.signal();
}
catch (Exception e)
{
}finally{
lock.unlock();
}
}
}
class Producer implements Runnable
{
private Resource res;
int x=0;
Producer(Resource res)
{
this.res=res;
}
public void run()
{
while(x<1000)
{
x++;
res.set("商品");
}
}
}
class Consumer implements Runnable
{
private Resource res;
int x=0;
Consumer(Resource res)
{
this.res=res;
}
public void run()
{
while(x<1000)
{
x++;
res.out();
}
}
}