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");