八.线程插队:
class joinThreaddemo
{ public static void main(String[] args)
{ demo d=new demo("demo");
Thread t1=new Thread(d);
Thread t2=new Thread(d);
t1.start(); 主线程执行到这个地方,t1加入执行,主线程释放执行权,等待t1执行完毕主线程继续执行。
try{t1.join();}
catch(InterruptedException e){} //一般用于临时加入执行的运算线程,让该线程运算完,该程序继续执行。
t2.start();
for(int i=0;i<10;i++)
{
System.out.println("main.............."+i);
System.out.println("over");}}
class demo implements Runnable{
public void run()
{for(int i=0;i<10;i++)
{System.out.println(Thread.currentThread().getName()+" "+i);}}
九.线程安全
package base2;
class Teacher implements Runnable {
private object obj =new object(); //obj相当于是锁。同步锁private int paper=15;public void run(){
while(true)
{
{
synchronized(obj)
if(paper>0)
{ //要让线程在此暂停片刻,出现错误数据
try{Thread.sleep(10);}
catch(InterruptedException e){}
Thread th=Thread.currentThread();
System.out.println(th.getName()+"正在分发第 "+paper--+"试卷");
}
}
}
}
package base2;
public class Example2
{
public static void main(String[] args) {
Teacher t=new Teacher();
new Thread(t,"王老师").start();
new Thread(t,"李老师").start();
new Thread(t,"朱老师").start();
}
}
出错原因:线程任务中有操作共同的数据
线程任务操作共享数据的代码有多条(运算有多个)。
解决的思路:只要让一个线程中在执行线程任务时将共享的数据的 代码执行完,不让其他线程进行运算。
代码体现:Java中解决此问题通过代码块来完成,叫做同步代码块。synchronized(对象){需要被同步的代码}
同步代码块解决了多线程的安全性问题。
同步的弊端:降低了程序的性能。
同步的前提:必须保证多个线程在同步中使用的同一个锁,通过这个前提可以确定同步是否写正确。
同步方法:
public void run()
{
if(flag)
{
while(true)
{
synchronized(this)
if(paper>0)
{ //要让线程在此暂停片刻,出现错误数据
try{Thread.sleep(10);
}
catch(InterruptedException e){}
Thread th=Thread.currentThread();
System.out.println(th.getName()+"正在分发第 "+paper--+"试卷");
}
}
}
else while(true){this.sale():
}
}
}
public void sale() //同步函数使用的锁对象this
{ if(paper>0)
{ //要让线程在此暂停片刻,出现错误数据
try{Thread.sleep(10);}
catch(InterruptedException e){}
Thread th=Thread.currentThread();
System.out.println(th.getName()+"正在分发第 "+paper--+"试卷");
}
}
package base2;public class Example2
{
{
public static void main(String[] args)
Teacher t=new Teacher(); 切换标记之前,让主线程停一会,这时就只有第一个在执行同步代码。
new Thread(t,"王老师").start();
try{Thread.sleep(10);}
catch(InterruptedException e){}
t.flag=false;
new Thread(t,"李老师").start();
}
}
同步的另一种方式:同步函数同步函数的锁:this,如果同步代码块中的对象和同步函数中的对象一致时,就同步了。 若同步代码快中的对象和同步函数中的对象不一致时,就不同步,就出现错误数据。让两个线程一个在同步代码块里执行,另一个在同步函数里执行。同步 函数和同步代码块的区别:同步函数的锁是this,同步代码块的锁可以是任意对象。线程中有多个任务时要用锁区分,同步代码块较常用。static 同步函数的锁是字节码文件对象,类名.class当线程任务出现了多个同步(多个锁)时,如果同步中嵌套了其他的同步时,容易引发死锁问题。死锁问题尽量不写。
class deadLock
{
public Static void main(String[] args)
{
Test t1=new Test(true);
Test t2=new Test(false);
Thread t11=new Thread(t1);
Thread t22=new Thread(t2);
t11.start();
t22.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(Thred.currentThred().getName()+"......if......locka ");
Synchronized(Mylock.lockB)
{
System.out.println(Thred.currentThred().getName()+"......if......lockb ");
}
}
}
}
else
{
while(true)
{
Synchronized(Mylock.lockB)
{
System.out.println(Thred.currentThred().getName()+"......else......lockB ");
}
Synchronized(Mylock.lockA){System.out.println(Thred.currentThred().getName()+"......else......lockA ");}
}
}
}
}
}
class Mylock
{
public static final object lockA=new object();
public static final object lockB=new object();
}
十.多线程通信: