------- android培训、java培训、期待与您交流! ----------
同步函数:
show();方法本身没有同步性,但我们加上sychronized标记后就具备了同步性。
class Ticket implements Runnable
{
private int num = 100;
//private Object obj = new Object(); 同步函数使用的锁是this 这里我们将boject注释掉,程序也没问题,
public void run()
{
while(true)
{
show();
}
}
//同步函数
public synchronized void show()
{
if(num>0)
{
try{Thread.sleep(10);}catch(InterruptedException e){}
System.out.println(Thread.currentThread().getName()+".....sale....."+num--);
}
}
}
class TicketDemo3
{
public static void main(String[] args)
{
Ticket t = new Ticket();
//创建线程对象。
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
Thread t3 = new Thread(t);
Thread t4 = new Thread(t);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
那么同步函数和同步代码块的区别是:①书写,同步函数书写简单②用的锁不一样,同步函数使用的锁是this;同步代码块使用的锁是任意对象
然而当静态方法在编译的时候还没有this也没有对象,所以静态方法若要同步,使用的锁是该类字节码文件对象----表示方式:类名.class
死锁
最常见的死锁情况,同步的嵌套:同步中还有同步,两个同步用的不是一个锁。
我们应当,尽量避免同步嵌套的情况。
class Clock { //锁使用的2个对象
public static Clock locka = new Clock();
public static Clock lockb = new Clock();
}
class DeadLock implements Runnable {
private boolean flag; //定义Boolean变量
public DeadLock(boolean flag){
this.flag = flag;
}
@Override
public void run() {
if(flag){ //让2个线程进入不同的锁当中
while(true){
synchronized(Clock.locka){ //线程T1在locka的锁准备进入lockb的锁中
System.out.println(".................if locka");
synchronized(Clock.lockb){
System.out.println(".................if lockb");
}
}
}
}
else{
while(true){
synchronized(Clock.lockb){ 线程t2在lockb的锁中准备进入locka的锁中
System.out.println("-------------------------else lockb");
synchronized(Clock.locka){
System.out.println("----------------------else locka");
}
}
}
}
}
}
public class DeadLockTest {
public static void main(String[] args) {
DeadLock d1 = new DeadLock(true); //创建对象,并设定Boolean值
DeadLock d2 = new DeadLock(false); <span style="font-family: Arial;">//创建对象,并设定Boolean值</span>
Thread t1 = new Thread(d1); //创建线程,传人对象
Thread t2 = new Thread(d2);
t1.start(); //开启线程
t2.start();
}
}
例中,当先线程当t1 拿到 Clock.locka , 当线程t2 拿到 Clock.lockb时,线程t1 需要
Clock.lockb 来继续运行,线程t2 需要 Clock.locka 来继续运行,而此时锁中都有运行着的线程,对方不能进入,造成了死锁的状况。
java中的等待唤醒机制
class Resource {
private String name ;
private String sex;
private boolean flag = false;
public synchronized void set(String name , String sex){
if(flag)
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
this.name = name; //设置成员变量
this.sex = sex;
flag = true; //设置之后,Resource中有值,将标记该为 true ,
this.notify(); //唤醒output
}
public synchronized void out(){
if(!flag)
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("The name is : " + name + " && The sex is : " + sex); //输出线程将数据输出
flag = false;//改变标记,以便输入线程输入数据
this.notify(); //唤醒input,进行数据输入
}
}
class Input implements Runnable {
private Resource r;
public Input(Resource r){
this.r = r;
}
public void run() {
int count = 0 ;
while(true){
if(count == 0){
r.set("Tom", "man");
}else{
r.set("Lily", "woman");
}
count = (count + 1)%2; //每执行到一次设置一次name和性别。
}
}
}
class Output implements Runnable {
private Resource r ;
public Output(Resource r ){
this.r = r;
}
public void run() {
while(true){
r.out();
}
}
}
public class ResorseDemo {
public static void main(String[] args) {
Resource r = new Resource(); //资源对象
Input in = new Input(r); //任务对象
Output out = new Output(r);
Thread t1 = new Thread(in); //线程对象
Thread t2 = new Thread(out);
t1.start(); //开启线程t1
t2.start();
}
}
在这个例子中,我们应用了等待唤醒机制:input() 和output()利用wait()和notify();及设置Boolean值来交替输入和打印一组姓名----年龄。
线程的优先级
当有多个线程同时处于可执行状态(就绪状态)哄抢CPU控制权时
优先级能够使得优先级高的线程有更大的机会获得 CPU 控制权,优先级低的线程机会要小
JAVA 里面定义了10级
可以用setPriority来设置线程的优先级,getPriority取得线程的优先级:
import sharevar.Machine;
public class priority extends Thread {
private static StringBuffer log=new StringBuffer();
private static int count=0;
public void run() {
for (int a=0;a<20;a++) {
log.append(currentThread().getName()+":"+a);
if (++count %10==0) log.append("\n");
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Machine m1=new Machine();
Machine m2=new Machine();
m1.setName("m1");
m2.setName("m2");
Thread main=Thread.currentThread(); //获得主线程
//查看和设置线程的优先级
System.out.println("default priority of main:"+main.getPriority());
//打印m2线程默认优先级
System.out.println("default priority of m1:"+m1.getPriority());
//打印m2线程默认优先级
System.out.println("default priority of m2:"+m2.getPriority());
m2.setPriority(Thread.MAX_PRIORITY);
m1.setPriority(Thread.MIN_PRIORITY);
m1.start();//开启线程
m2.start();
System.out.println(log);
}
}