一、创建线程的两种方式
(一)继承Thread类
class ClassName extends Thread{
public void run(){}
}
new ClassName().start();
(二)实现Runnable接口
class ClassName implements Runnable{
public void run(){}
}
new Thread(new ClassName()).start;
二、线程同步
在多线程的程序中,当多个线程并发执行时,由于线程的相对执行顺序不确定,当涉及到对共享数据的操作时,会导致执行结果的不确定,因此需要对线程的并发操作进行控制。
Java中对共享数据操作的并发控制是采用传统的封锁技术。
临界区的控制是通过对象锁来进行的。Java平台将每个由synchronized(someObject){}语句指定的对象someObject设置一个锁,称为对象锁。当一个线程获得对象的锁后,便拥有了该对象的操作权,其他任何线程不能对该对象进行任何操作。
线程间的交互使用wait()和notify()方法。
如果线程调用了某个对象X的wait()方法,则该线程将放入X的wait pool,并且该线程将释放X的锁,当线程调用X的notify()方法,将会使对象X的wait pool中的一个线程移入lock pool,在lock pool中等待X的锁,一旦获得即可运行。
三、生产者和消费者的例子
(一)线程之间没有交互
class Mystack{
private char str[] = new char[5];
private int index = 0;
public void push (char c){
synchronized(this){
str[index] = c;
index++;
}
}
public char pop (){
synchronized(this){
index--;
return str[index];
}
}
public int getIndex(){
return index;
}
}
class Producer implements Runnable{
Mystack s;
char temp;
public Producer(Mystack s){
this.s = s;
}
public void run(){
for(int i = 0;i < 15;i++){
if( s.getIndex() < 5 ){
temp = (char)(Math.random() * 5 + 'a');
s.push(temp);
System.out.println("Produce: " + temp );
try{
Thread.sleep(20);
}catch(Exception e){}
}
}
}
}
class Consumer implements Runnable{
Mystack s;
char temp;
public Consumer(Mystack s){
this.s = s;
}
public void run(){
while( true ){
while( true ){
if( s.getIndex() > 0 ){
temp = s.pop();
System.out.println("Consumer: " + temp );
try{0000000000
Thread.sleep(25);
}catch(Exception e){}
}
}
}
}
}
public class PC{
public static void main (String[] args){
Mystack s = new Mystack();
Producer p = new Producer(s);
Consumer c = new Consumer(s);
new Thread(p).start();
new Thread(c).start();
}
}
(二)线程之间相互通信
class Mystack{
private char str[] = new char[5];
private int index = 0;
public void push (char c){
synchronized(this){
if( index == 5 )
try{
this.wait();
}catch( Exception e ){}
str[index] = c;
index++;
this.notify();
}
}
public char pop (){
synchronized(this){
if( index == 0 )
try{
this.wait();
}catch( Exception e ){}
index--;
char temp = str[index];
this.notify();
return temp;
}
}
public int getIndex(){
return index;
}
}
class Producer implements Runnable{
Mystack s;
char temp;
public Producer(Mystack s){
this.s = s;
}
public void run(){
for( int i = 0;i < 300;i++){
temp = (char)(Math.random() * 5 + 'a');
s.push(temp);
System.out.println("produce : " + temp);
}
}
}
class Consumer implements Runnable{
Mystack s;
char temp;
public Consumer(Mystack s){
this.s = s;
}
public void run(){
while( true ){
temp = s.pop();
System.out.println("consumer : " + temp);
}
}
}
public class NPC{
public static void main (String[] args){
Mystack s = new Mystack();
Producer p = new Producer(s);
Consumer c = new Consumer(s);
new Thread(p).start();
new Thread(c).start();
}
}