java编程笔记21 线程

java

1,两种方法来创建线程:

1)继承Thread类实现run方法:

public class Hello1 extends Thread

{

String name;

public Hello1(String n)

{

name = n;

}

public void run()

{

for (int i=1; i<=10; i++)

{

System.out.println(name+" Hello "+i);

}

}

}

2)实现Runnable接口,实现run方法:

public class Hello2 implements Runnable

{

String name;

public Hello2(String n)

{

name = n;

}

public void run()

{

for (int i=1; i<=10; i++)

System.out.println(name+" Hello "+i);

}

}

推荐第二种方法;

2,产生Thread对象和启动线程

public class ThreadsExample1

{

public static void main(String argv[])

{

Hello1 h1 = new Hello1("Thread1");

Hello2 h2 = new Hello2("Thread2");

Thread t1 = new Thread(h1);

Thread t2 = new Thread(h2);

t1.start();

t2.start();

}

}

3,停止线程运行

下面的run方法可以让线程一直运行:

public class Hello3 implements Runnable

{

String name;

public Hello3(String n)

{

name = n;

}

public void run()

{

int i=0;

while(true)//这样来写run方法

{

i++;

System.out.println(name+" Hello "+i);

}

}

}

加一个循环条件来达到停止现成的效果:

public class Hello4 implements Runnable

{

String name;

Boolean isStop;

public Hello4(String n)

{

name = n;

isStop = false;

}

public void run()

{

int i=0;

while(!isStop)

{

i++;

System.out.println(name+" Hello "+i);

}

}

public void stop()//控制条件

{

isStop = true;

}

}

当一个线程对象进入死亡状态后,就没有任何方法可以回到其他状态。

4,暂停线程运行

sleep方法:

yield方法

join方法,

来看join的一个例子:

MotherThread:

package ch22;

public class MotherThread implements Runnable

{

public void run()

{

System.out.println("妈妈准备煮饭");

System.out.println("妈妈发现米酒用完了");

System.out.println("妈妈叫儿子去买米酒");

Thread son = new Thread(new SonThread());

son.start();

System.out.println("妈妈等待儿子把米酒买回来");

try {

son.join();

}

catch (InterruptedException ie)

{

System.err.println("发生异常!");

System.err.println("妈妈中断煮饭");

System.exit(1);

}

System.out.println("妈妈开始煮饭");

System.out.println("妈妈煮好饭了");

}

}

SonThread:

package ch22;

public class SonThread implements Runnable

{

public void run()

{

System.out.println("儿子出门去买米酒");

System.out.println("儿子买东西来回需5分钟");

try {

for (int i=1; i<=5; i++)

{

Thread.sleep(1000);

System.out.print(i+"分钟 ");

}

}

catch (InterruptedException ie)

{

System.err.println("儿子发生意外");

}

System.out.println("\n儿子买米酒回来了");

}

}


Cooking:

package ch22;

public class Cooking

{

public static void main(String argv[])

{

Thread mother = new Thread(new MotherThread());

mother.start();

}

}

运行结果:

5,数据同步处理

现在我们有这样一个线程:

package ch22;

public class ShareData implements Runnable

{

int i;

public void run()

{

while (i<10)

{

i++;

for(int j=0; j<10000000; j++);

System.out.println(Thread.currentThread().getName()+":"+i);

}

}

}

现在我们来产生两个ShareData对象,并给两个Thread运行:

package ch22;

public class ThreadsExample2

{

public static void main(String argv[])

{

ShareData s1 = new ShareData();

ShareData s2 = new ShareData();

Thread t1 = new Thread(s1);

Thread t2 = new Thread(s2);

t1.start();

t2.start();

}

}

其结果如图:

可以看到,两个Thread对象在交互运行,Thread 0和Thread 1分别从0按顺序到10.

这是因为两个Thread共用了程序代码但是没有共用数据,下面我们来看程序代码和数据都共用的效果:

package ch22;

public class ThreadsExample3

{

public static void main(String argv[])

{

ShareData s = new ShareData();

Thread t1 = new Thread(s);//两个小成共用一个对象ShareData

Thread t2 = new Thread(s);

t1.start();

t2.start();

}

}

结果并不是你所想象的从0到10,而是:

这是为什么呢????

这是因为线程被分割运行了,具体分析略。

6,synchronized实现线程同步

synchronized(要取得锁的对象)

{

  要锁定的代码

}

package ch22;

public class SyncShareData implements Runnable

{

int i;

public void run()

{

while (i<10)

{

/*锁的对象是SyncShareData自己,也就是说这个对象对应的线程要进行同步机制*/

synchronized(this)

{

i++;

for(int j=0; j<10000000; j++);

System.out.println(Thread.currentThread().getName()+":"+i);

}

}

}

}

package ch22;

public class ThreadsExample4

{

public static void main(String argv[])

{

SyncShareData s = new SyncShareData();

/*t1和t2都是操作同一个SyncShareData对象的线程,

* 要进行同步机制,因为SyncShareData实现了锁机制*/

Thread t1 = new Thread(s);

Thread t2 = new Thread(s);

t1.start();

t2.start();

}

}

实现了两个线程对同一个对象操作的同步

7,等待wait与通报notify

生产者和消费者的例子:

package ch22;

public class Storage

{

private int count;//当前库存值

private int size;//最大库存量

public Storage(int s)

{

size = s;

}

//类里的方法实现了锁,则调用这个方法必须取得这个类的对象的锁

public synchronized void addData(String n)

{

while (count == size)//注意为什么要用while循环而不是if

{

try {

this.wait();//进入等待状态

}

catch (InterruptedException e) { }

}

this.notify();//通知消费者可以消费了

count++;

System.out.println(n+" make data count: "+count);

}

public synchronized void delData(String n)

{

while (count == 0)

{

try {

this.wait();

}

catch (InterruptedException e) { }

}

this.notify();

System.out.println(n+" use data count: "+count);

count--;

}

}

package ch22;

public class Producer extends Thread

{

private String name;

private Storage s;

public Producer(String n, Storage s)

{

name = n;

this.s = s;

}

public void run()

{

while (true)

{

s.addData(name);

try {

sleep((int)Math.random()*3000);

}

catch (InterruptedException e) { }

}

}

}

package ch22;

public class Consumer extends Thread

{

private String name;

private Storage s;

public Consumer(String n, Storage s)

{

name = n;

this.s = s;

}

public void run()

{

while (true)

{

s.delData(name);

try {

sleep((int)Math.random()*3000);

}

catch (InterruptedException e) { }

}

}

}

package ch22;

public class ThreadsExample5

{

public static void main(String argv[])

{

Storage s = new Storage(3);

Producer p1 = new Producer("Producer1", s);

Producer p2 = new Producer("Producer2", s);

Consumer c1 = new Consumer("Consumer1", s);

p1.start();

p2.start();

c1.start();

}

}

.........

Producer1 make data count: 3
Consumer1 use data count: 3
Consumer1 use data count: 2
Producer1 make data count: 2
Consumer1 use data count: 2
Producer1 make data count: 2

.........

以上是 java编程笔记21 线程 的全部内容, 来源链接: utcz.com/z/390467.html

回到顶部