운영 체제를 배울 때 하나의 지식 포인트는 한 번에 하나의 프로세스에서만 작동할 수 있는 리소스입니다. 멀티 스레딩을 사용하면 동시에 작동하며 동시에 하나의 리소스에 대한 액세스 및 수정을 제어할 수 없습니다. 제어하려는 경우 오늘은 첫 번째 방법인 스레드 동기화 블록 또는 스레드 동기화에 대해 이야기하겠습니다. 메서드( 동기화)
다음은
synchronized
키워드synchronized
关键字的使用
public class Sychor {public void insert(Thread thread) {for (int i = 0; i < 10; i++) { System.out.println(thread.getName() + "输出: " + i); } }public static void main(String[] args) {final Sychor sychor = new Sychor(); Thread t1 = new Thread() {public void run() { sychor.insert(Thread.currentThread()); }; }; Thread t2 = new Thread() {public void run() { sychor.insert(Thread.currentThread()); }; }; t1.start(); t2.start(); } }
其中输出结果为下图
从上面的结果可以看出这里的两个线程是同时执行
insert()
方法的,下面我们在原有的代码上添加synchronized
关键字看看效果如何,代码如下:
public class Sychor {public synchronized void insert(Thread thread) {for (int i = 0; i < 10; i++) { System.out.println(thread.getName() + "输出: " + i); } }public static void main(String[] args) {final Sychor sychor = new Sychor(); Thread t1 = new Thread() {public void run() { sychor.insert(Thread.currentThread()); }; }; Thread t2 = new Thread() {public void run() { sychor.insert(Thread.currentThread()); }; }; t1.start(); t2.start(); } }
上面程序的동기화란 무엇입니까? 동기화를 사용하는 방법은 무엇입니까?我就不列出来,自己可以试试,总之就是加上了
synchronized
关键字使得线程是一个一个的执行的,只有先执行完一个线程才能执行了另外一个线程。
当然上面的我们使用的是线程同步方法,我们可以使用线程同步块,这两个相比线程同步块更加灵活,只需要将需要同步的代码放在同步块中即可,代码如下;
public class Sychor {public void insert(Thread thread) {synchronized (this) {for (int i = 0; i < 10; i++) { System.out.println(thread.getName() + "输出: " + i); } } }public static void main(String[] args) {final Sychor sychor = new Sychor(); Thread t1 = new Thread() {public void run() { sychor.insert(Thread.currentThread()); }; }; Thread t2 = new Thread() {public void run() { sychor.insert(Thread.currentThread()); }; }; t1.start(); t2.start(); } }
从上面的代码中可以看出这种方式更加灵活,只需要将需要同步的代码方法在同步块中,不需要同步的代码放在外面
我们知道每一个对象都有一把锁,当我们使用线程同步方法或者线程同步块的时候实际上获得是对象的唯一的一把锁,当一个线程获得了这唯一的锁,那么其他的线程只能拒之门外了,注意这里我们说是一个对象,也就是说是同一个对象,如果是不同的对象,那么就不起作用了,因为不同对象有不同的对象锁,比如我们将上面的程序改成如下:
public class Sychor {public void insert(Thread thread) {synchronized (this) {for (int i = 0; i < 10; i++) { System.out.println(thread.getName() + "输出: " + i); } } }public static void main(String[] args) {//第一个线程Thread t1 = new Thread() {public void run() { Sychor sychor = new Sychor(); //在run() 方法中创建一个对象sychor.insert(Thread.currentThread()); }; };//第二个线程Thread t2 = new Thread() {public void run() { Sychor sychor = new Sychor(); //创建另外的一个对象sychor.insert(Thread.currentThread()); }; }; t1.start(); t2.start(); } }
从上面的结果可知,此时线程同步块根本不起作用,因为他们调用的是不同对象的insert方法,获得锁是不一样的
上面我们已经说过一个对象有一把锁,线程同步方法和线程同步块实际获得的是对象的锁,因此线程同步块的括号中填入的是
this
,我们都知道this
在一个类中的含义
一个类也有唯一的一把锁,我们前面说的是使用对象调用成员方法,现在如果我们要调用类中的静态方法,那么我们可以使用线程同步方法或者同步块获得类中的唯一一把锁,那么对于多个线程同时调用同一个类中的静态方法就可以实现控制了,代码如下:
public class Sychor {// 静态方法public static synchronized void insert(Thread thread) {for(int i=0;i<10;i++) { System.out.println(thread.getName()+"输出 "+i); } }public static void main(String[] args) {//第一个线程Thread t1 = new Thread() {public void run() { Sychor.insert(Thread.currentThread()); //直接使用类调用静态方法}; };//第二个线程Thread t2 = new Thread() {public void run() { Sychor.insert(Thread.currentThread()); //直接使用类调用静态方法}; }; t1.start(); t2.start(); } }
要想实现线程安全和同步控制,如果执行的是非
static
同步方法或者其中的同步块,那么一定要使用同一个对象,如果调用的是static同步方法或者其中的同步块那么一定要使用同一个类去调用
如果一个线程访问的是
static
同步方法,而另外一个线程访问的是非static的同步方法,此时这两个是不会发生冲突的,因为一个是类的锁,一个是对象的锁
如果使用线程同步块,那么同步块中的代码是控制访问的,但是外面的代码是所有线程都可以访问的
当一个正在执行同步代码块的线程出现了异常,那么
jvm
스레드 동기화 방법
rrreee
위 결과에서 여기 두 스레드가
insert()
메서드를 동시에 실행하는 것을 볼 수 있습니다. 다음으로 synchronized를 원래 코드에 적용하여 효과를 확인하면 코드는 다음과 같습니다.🎜🎜synchronized
키워드가 추가되어 스레드가 하나씩 실행됩니다. 한 스레드가 먼저 실행되어야 다른 스레드가 실행될 수 있습니다. 🎜🎜this
로 채워집니다. 우리 모두는 클래스🎜🎜🎜🎜🎜🎜🎜🎜클래스에서 this
의 의미를 알고 있습니다. 고유 잠금 앞서 말한 것은 개체를 사용하여 멤버 메서드를 호출하는 것입니다. 이제 클래스에서 정적 메서드를 호출하려면 스레드 동기화 메서드나 동기화 블록을 사용하여 유일한 잠금을 얻을 수 있습니다. 클래스를 잠그면 여러 스레드가 동시에 동일한 클래스의 정적 메서드를 호출하여 달성할 수 있습니다. 제어되는 코드는 다음과 같습니다. 🎜🎜🎜🎜정적
인 경우 스레드 안전성과 동기화 제어를 달성하려면 >동기화된 메서드 또는 동기화된 블록이 정적 동기화 메서드 또는 동기화된 블록인 경우 동일한 개체를 사용해야 합니다. 호출된 경우 동일한 클래스를 사용하여 호출해야 합니다. 한 스레드가 정적
동기화 메서드에 액세스하고 다른 스레드가 비정적 동기화 메서드에 액세스하는 경우 두 스레드는 충돌하지 않습니다. 하나는 클래스 잠금이고 다른 하나는 객체 잠금이기 때문입니다🎜 🎜🎜🎜🎜🎜🎜🎜스레드 동기화 블록을 사용하는 경우 동기화 블록의 코드는 액세스가 제어되지만 외부 코드는 모든 스레드에서 액세스 가능합니다. 🎜🎜🎜🎜🎜🎜🎜🎜동기화된 코드 블록이 실행 중일 때 스레드에서 예외가 발생하면 jvm
은 현재 스레드가 차지한 잠금을 자동으로 해제하므로 교착 상태가 발생하지 않습니다. 예외🎜🎜🎜🎜🎜참조 기사🎜🎜🎜🎜🎜🎜위 내용은 동기화란 무엇입니까? 동기화를 사용하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!