黑马程序员——java基础:线程

------- android培训java培训、期待与您交流! ----------

一,什么是线程

就是进程中的一个独立的控制单元。
线程在控制着进程的执行。

二 创建线程的两种方式

1.创建线程的第一种方式:继承Thread类。

步骤:
1,定义类继承Thread。


2,复写Thread类中的run方法。
目的:将自定义代码存储在run方法。让线程运行。


3,调用线程的start方法,
该方法两个作用:启动线程,调用run方法。

实例

class Demo extends Thread
{
	public void run()
	{
		for(int x=0; x<60; x++)
			System.out.println("demo run----"+x);
	}
}





class ThreadDemo 
{
	public static void main(String[] args) 
	{
		//for(int x=0; x<4000; x++)
		//System.out.println("Hello World!");

		Demo d = new Demo();//创建好一个线程。
		//d.start();//开启线程并执行该线程的run方法。
		d.run();//仅仅是对象调用方法。而线程创建了,并没有运行。

		
		for(int x=0; x<60; x++)
			System.out.println("Hello World!--"+x);
		

	

	
	}
}
2,创建线程的第二种方式:实现Runnable接口。


步骤:
1,定义了实现Runnable接口。
2,覆盖接口的run方法。将多线程要运行的代码存入其中。
3,创建Thread类的对象(创建线程),并将Runnable接口的子类对象作为参数传递给Thread的构造函数。
为什么要传递?因为线程要运行的代码都在Runnable子类的run方法中存储。所以要将该run方法所属的对象
传递给Thread。让Thread线程去使用该对象调用其run方法。
4,调用Thread对象的start方法。开启线程。

实例

class Thread 
{
	private Runnable target;

	Thread()
	{
	}
	Thread(Runnable target)
	{
		this.target = target;
	}

	public void run()
	{
		if(target!=null)
			target.run();
	}
}

class Test implements Runnable
{
	public void run()
	{}
}


main()
{
	Test q = new Test();
	Thread t = new Thread(q);
}


class Demo extends Thread
{
	public void run()
	{
	}
}
class  
{
	public static void main(String[] args) 
	{
		System.out.println("Hello World!");
	}
}


三,线程间通信。

1,线程间通信。
等待/唤醒机制。


也就是常见的生产者消费者问题。


1.当多个生产者消费者出现时,
需要让获取执行权的线程判断标记。
通过while完成。


2.需要将对方的线程唤醒。
仅仅用notify,是不可以的。因为有可能出现只唤醒本方。
有可能会导致,所有线程都等待。
所以可以通过notifyAll的形式来完成 。






这个程序有一个bug。就是每次notifyAll。都会唤醒本方。
可不可以只唤醒对方呢?


JDK1.5版本提供了一些新的对象,优化了等待唤醒机制。


1,将synchronized 替换成了Lock接口。
将隐式锁,升级成了显示锁。
Lock
获取锁:lock();
释放锁:unlock();注意:释放的动作一定要执行,所以通常定义在finally中。
获取Condition对象:newCondition();
2,将Object中的wait,notify,notifyAll方法都替换成了Condition的await,signal,signalAll。
和以前不同是:一个同步代码块具备一个锁,该所以具备自己的独立wait和notify方法。
现在是将wait,notify等方法,封装进一个特有的对象Condition,而一个Lock锁上可以有多个Condition对象。

Lock lock = new ReentrantLock();

Condition conA = lock.newCondition();
Condition conB = lock.newCondition();


con.await();//生产,,消费

con.signal();生产

set()
{
if(flag)
conA.await();//生产者,
code......;


flag = true;
conB.signal();
}

out()
{
if(!flag)
conB.await();//消费者


code....;
flag = false;
conA.signal();
}



wait和sleep的区别:
wait:释放cpu执行权,释放同步中锁。
sleep:释放cpu执行权,不释放同步中锁。


synchronized(锁)
{
wait();
}


停止线程:
stop过时。
原理:run方法结束。run方法中通常定义循环,指定控制住循环线程即可结束。


1,定义结束标记。
2,当线程处于了冻结状态,没有执行标记,程序一样无法结束。
这时可以循环,正常退出冻结状态,或者强制结束冻结状态。
强制结束冻结状态:interrupt();目的是线程强制从冻结状态恢复到运行状态。
但是会发生InterruptedException异常。


线程中一些常见方法:
setDaemon(boolean):将线程标记为后台线程,后台线程和前台线程一样,开启,一样抢执行权运行,
只有在结束时,有区别,当前台线程都运行结束后,后台线程会自动结束。


join():什么意思?等待该线程结束。当A线程执行到了B的.join方法时,A就会处于冻结状态。
A什么时候运行呢?当B运行结束后,A就会具备运行资格,继续运行。


加入线程,可以完成对某个线程的临时加入执行。

实例:获取两个字符串中最大相同子串。第一个动作:将短的那个串进行长度一次递减的子串打印。
"abcwerthelloyuiodef"
"cvhellobnm"
思路:
1,将短的那个子串按照长度递减的方式获取到。
2,将每获取到的子串去长串中判断是否包含,
如果包含,已经找到!。

class  StringTest3
{
	/*
	练习四。
	*/
	public static String getMaxSubString(String s1,String s2)
	{

		String max = "",min = "";

		max = (s1.length()>s2.length())?s1: s2;

		min = (max==s1)?s2: s1;
		
//		sop("max="+max+"...min="+min);
		for(int x=0; x<min.length(); x++)
		{
			for(int y=0,z=min.length()-x; z!=min.length()+1; y++,z++)
			{
				String temp = min.substring(y,z);
				
				sop(temp);
				if(max.contains(temp))//if(s1.indexOf(temp)!=-1)
					return temp;
			}
		}
		return "";
	}


	public static void main(String[] args) 
	{
		String s1 = "ab";
		String s2 = "cvhellobnm";
		sop(getMaxSubString(s2,s1));
	}

	public static void sop(String str)
	{
		System.out.println(str);
	}
}

实例:获取一个字符串在另一个字符串中出现的次数。
"abkkcdkkefkkskk"

思路:
1,定义个计数器。
2,获取kk第一次出现的位置。
3,从第一次出现位置后剩余的字符串中继续获取kk出现的位置。
每获取一次就计数一次。
4,当获取不到时,计数完成。

class  StringTest2
{

	/*
	练习三。

	*/
	
	public static int getSubCount(String str,String key)
	{
		int count = 0;
		int index = 0;

		while((index=str.indexOf(key))!=-1)
		{
			sop("str="+str);
			str = str.substring(index+key.length());

			count++;	
		}
		return count;
	}

	/*
	练习三,方式二。

	*/
	public static int getSubCount_2(String str,String key)
	{
		int count = 0;
		int index = 0;

		while((index= str.indexOf(key,index))!=-1)
		{
			sop("index="+index);
			index = index + key.length();

			count++;
		}
		return count;
	}

	public static void main(String[] args) 
	{
		String str = "kkabkkcdkkefkks";

		///sop("count====="+str.split("kk").length);不建议使用。

		sop("count="+getSubCount_2(str,"kk"));
	}

	public static void sop(String str)
	{
		System.out.println(str);
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值