小菜鸟也想飞的java笔记——java多线程学习笔记

JAVA多线程Synchronized关键字

Test19_Thread

packagecom.ygtq.review.basic;

这里的程序根本不能体现单线程与多线程的差别,无论是单线程还是多线程都会交替输出.MyClass类中的count++计算使用了同步机制,于是不允许2个线程同时对myClass对象的count进行计算,但是这里同步代码非常短,当线程A执行完count++并输出后该同步代码块就结束了,释放了对象锁,此时其他线程就可以争夺myClass,此时的线程有threadA和threadB,于是他们都有机会夺取myClass对象的对象锁进行访问。

正确的做法是:如Test20.java中所写,在MyCLass类中进行循环,从而可以体现线程对该myClass占用了较长时间,在此时间内其他线程无法占用。即在线程案例中,循环和休眠总是要放在受synchronized同步保护的资源处

public classTest19_Thread {

         public static void main(String[] args){

                   Thread threadA=new Thread(newThreadA());

                   threadA.start();

                   Thread threadB=new Thread(newThreadB());

                   threadB.start();

         }

}

//可以公共访问的资源

class MyClass{

         static int count;

         String name;

         public void myMethod(){

                   synchronized (this) {

                            StringthreadName=Thread.currentThread().getName();

                            System.out.println(threadName+"  "+(count++));

                   }

         }

}

//线程1

class ThreadAimplements Runnable{

         public void run() {

                   MyClass class1=new MyClass();

                   for (int i = 0; i <5; i++) {

                            class1.myMethod();

                            try {

                                     Thread.sleep(1000);

                            } catch(InterruptedException e) {

                                     e.printStackTrace();

                            }

                   }

         }

}

class ThreadBimplements Runnable{

         public void run() {

                   MyClass class1=new MyClass();

                   for (int i = 0; i <5; i++) {

                            class1.myMethod();

                            try {

                                     Thread.sleep(1000);

                            } catch(InterruptedException e) {

                                     e.printStackTrace();

                            }

                   }

         }

}

 

Test20_Thread

packagecom.ygtq.review.basic;

线程2 (线程1和线程2操作的是相同的资源,myClass对象)synchronize同步时只能对一个对象进行同步,即只对一个MyClass对象进行同步,即如果多个线程操作的是同一个myClass对象则会同步,如果操作的不是同一个对象,那么不会同步,理解:synchronize同步块必然属于某个类(对象),那么synchronize只是不允许多个线程同时操作同一个受synchronized保护的对象,如果几个线程操作的是不同的对象实例,是可以并发的,例如这里ThreadA和ThreadB中操作的myClass对象是不同的,即在这里2个线程操作的对象是2个不同的对象通过ThreadthreadA=new Thread(new ThreadA(myClass),"线程A")ThreadthreadB=new Thread(new ThreadA(myClass),"线程B")threadA.start();threadB.start();可以起2个线程,这是两个不同的线程,只不过执行的逻辑相同而已;但是继承Thread的方式创建线程不能同时起2个线程

public classTest20_Thread {

         public static void main(String[] args){

                   MyClass myClass=newMyClass();//使用的资源对象是myClass

                   Thread threadA=new Thread(newThreadA(myClass),"线程A");

                   //MyClass myClass2=newMyClass();//使用的资源对象是myClass2

                   Thread threadB=new Thread(newThreadA(myClass),"线程B");

                   threadA.start();

                   threadB.start();

                   ThreadC threadC=newThreadC();

                   threadC.start();

                   threadC.start();

         }

}

class MyClass{

         int count;

         String name;

         public void myMethod(){

                   synchronized (this) {

                            StringthreadName=Thread.currentThread().getName();

                            for (int i = 0; i< 5; i++) {

                                     System.out.println(threadName+"  "+(count++));

                                     try {

                                               Thread.sleep(1000);

                                     } catch (InterruptedExceptione) {

                                               e.printStackTrace();

                                     }

                            }

                   }

         }

}

//线程1

class ThreadAimplements Runnable{

         MyClass class1;

         public ThreadA(MyClass myClass) {

                   this.class1=myClass;

         }

         public void run() {

                   class1.myMethod();

         }

}

//线程2 (线程1和线程2操作的是相同的资源,myClass对象)

class ThreadBimplements Runnable{

         MyClass class2;

         public ThreadB(MyClass myClass) {

                   this.class2=myClass;

         }

         public void run() {

                   class2.myMethod();

         }

}

class ThreadCextends Thread{

         public void run() {

                   System.out.println("这是线程C");

         }

}

 

Test21_Thread

packagecom.ygtq.review.basic;

//当一个线程访问对象的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该对象中的非synchronized(this)同步代码块

public classTest21_Thread {

         public static void main(String[] args){

                   MyClass myClass=new MyClass();//使用的资源对象是myClass

                   Thread threadA=new Thread(newThreadA(myClass),"线程A");

                   //MyClass myClass2=newMyClass();//使用的资源对象是myClass2

                   Thread threadB=new Thread(newThreadB(myClass),"线程B");

                   threadA.start();

                   threadB.start();

         }

}

class MyClass{

         int count;

         String name;

         //这是一个进行同步的方法

         public void myMethod(){

                   synchronized (this) {

                            StringthreadName=Thread.currentThread().getName();

                            for (int i = 0; i< 5; i++) {

                                     System.out.println(threadName+"  "+(count++));

                                     try {

                                               Thread.sleep(1000);

                                     } catch(InterruptedException e) {

                                               e.printStackTrace();

                                     }

                            }

                   }

         }

         //这是一个非同步的方法

         public void myMethod2(){

                   StringthreadName=Thread.currentThread().getName();

                   for (int i = 0; i < 5;i++) {

                            System.out.println(threadName+": 这是非同步的方法");

                            try {

                                     Thread.sleep(1000);

                            } catch(InterruptedException e) {

                                     e.printStackTrace();

                            }

                   }

         }

}

//线程1

class ThreadAimplements Runnable{

         MyClass class1;

         public ThreadA(MyClass myClass) {

                   this.class1=myClass;

         }

         public void run() {

                   class1.myMethod();

         }

}

//线程2 (线程1和线程2操作的是相同的资源,myClass对象)

class ThreadBimplements Runnable{

         MyClass class2;

         public ThreadB(MyClass myClass) {

                   this.class2=myClass;

         }

         public void run() {

                   //调用的是MyClass中的非同步方法

                   class2.myMethod2();

         }

}

class ThreadCextends Thread{

         public void run() {

                   System.out.println("这是线程C");

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值